Line data Source code
1 : /* Get previous frame state for an existing frame state.
2 : Copyright (C) 2013, 2014, 2016 Red Hat, Inc.
3 : This file is part of elfutils.
4 :
5 : This file is free software; you can redistribute it and/or modify
6 : it under the terms of either
7 :
8 : * the GNU Lesser General Public License as published by the Free
9 : Software Foundation; either version 3 of the License, or (at
10 : your option) any later version
11 :
12 : or
13 :
14 : * the GNU General Public License as published by the Free
15 : Software Foundation; either version 2 of the License, or (at
16 : your option) any later version
17 :
18 : or both in parallel, as here.
19 :
20 : elfutils is distributed in the hope that it will be useful, but
21 : WITHOUT ANY WARRANTY; without even the implied warranty of
22 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : General Public License for more details.
24 :
25 : You should have received copies of the GNU General Public License and
26 : the GNU Lesser General Public License along with this program. If
27 : not, see <http://www.gnu.org/licenses/>. */
28 :
29 : #ifdef HAVE_CONFIG_H
30 : # include <config.h>
31 : #endif
32 :
33 : #include "cfi.h"
34 : #include <stdlib.h>
35 : #include "libdwflP.h"
36 : #include "../libdw/dwarf.h"
37 : #include <system.h>
38 :
39 : /* Maximum number of DWARF expression stack slots before returning an error. */
40 : #define DWARF_EXPR_STACK_MAX 0x100
41 :
42 : /* Maximum number of DWARF expression executed operations before returning an
43 : error. */
44 : #define DWARF_EXPR_STEPS_MAX 0x1000
45 :
46 : bool
47 : internal_function
48 3867 : __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
49 : {
50 3867 : Ebl *ebl = state->thread->process->ebl;
51 3867 : if (! ebl_dwarf_to_regno (ebl, ®no))
52 : return false;
53 3859 : if (regno >= ebl_frame_nregs (ebl))
54 : return false;
55 7718 : if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
56 3859 : & ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
57 : return false;
58 2163 : if (val)
59 2163 : *val = state->regs[regno];
60 : return true;
61 : }
62 :
63 : bool
64 : internal_function
65 2879 : __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val)
66 : {
67 2879 : Ebl *ebl = state->thread->process->ebl;
68 2879 : if (! ebl_dwarf_to_regno (ebl, ®no))
69 : return false;
70 2871 : if (regno >= ebl_frame_nregs (ebl))
71 : return false;
72 : /* For example i386 user_regs_struct has signed fields. */
73 2871 : if (ebl_get_elfclass (ebl) == ELFCLASS32)
74 879 : val &= 0xffffffff;
75 5742 : state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
76 2871 : ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)));
77 2871 : state->regs[regno] = val;
78 2871 : return true;
79 : }
80 :
81 : static bool
82 2779 : state_get_reg (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
83 : {
84 2779 : if (! __libdwfl_frame_reg_get (state, regno, val))
85 : {
86 884 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
87 884 : return false;
88 : }
89 : return true;
90 : }
91 :
92 : static int
93 468 : bra_compar (const void *key_voidp, const void *elem_voidp)
94 : {
95 468 : Dwarf_Word offset = (uintptr_t) key_voidp;
96 468 : const Dwarf_Op *op = elem_voidp;
97 468 : return (offset > op->offset) - (offset < op->offset);
98 : }
99 :
100 : struct eval_stack {
101 : Dwarf_Addr *addrs;
102 : size_t used;
103 : size_t allocated;
104 : };
105 :
106 : static bool
107 2530 : do_push (struct eval_stack *stack, Dwarf_Addr val)
108 : {
109 2530 : if (stack->used >= DWARF_EXPR_STACK_MAX)
110 : {
111 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
112 0 : return false;
113 : }
114 2530 : if (stack->used == stack->allocated)
115 : {
116 1632 : stack->allocated = MAX (stack->allocated * 2, 32);
117 : Dwarf_Addr *new_addrs;
118 1632 : new_addrs = realloc (stack->addrs,
119 : stack->allocated * sizeof (*stack->addrs));
120 1632 : if (new_addrs == NULL)
121 : {
122 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
123 0 : return false;
124 : }
125 1632 : stack->addrs = new_addrs;
126 : }
127 2530 : stack->addrs[stack->used++] = val;
128 2530 : return true;
129 : }
130 :
131 : static bool
132 : do_pop (struct eval_stack *stack, Dwarf_Addr *val)
133 : {
134 2530 : if (stack->used == 0)
135 : {
136 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
137 : return false;
138 : }
139 2530 : *val = stack->addrs[--stack->used];
140 : return true;
141 : }
142 :
143 : /* If FRAME is NULL is are computing CFI frame base. In such case another
144 : DW_OP_call_frame_cfa is no longer permitted. */
145 :
146 : static bool
147 1642 : expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
148 : size_t nops, Dwarf_Addr *result, Dwarf_Addr bias)
149 : {
150 1642 : Dwfl_Process *process = state->thread->process;
151 1642 : if (nops == 0)
152 : {
153 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
154 0 : return false;
155 : }
156 1642 : struct eval_stack stack =
157 : {
158 : .addrs = NULL,
159 : .used = 0,
160 : .allocated = 0
161 : };
162 :
163 : #define pop(x) do_pop(&stack, x)
164 : #define push(x) do_push(&stack, x)
165 :
166 : Dwarf_Addr val1, val2;
167 1642 : bool is_location = false;
168 1642 : size_t steps_count = 0;
169 4375 : for (const Dwarf_Op *op = ops; op < ops + nops; op++)
170 : {
171 2743 : if (++steps_count > DWARF_EXPR_STEPS_MAX)
172 : {
173 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
174 0 : return false;
175 : }
176 2743 : switch (op->atom)
177 : {
178 : /* DW_OP_* order matches libgcc/unwind-dw2.c execute_stack_op: */
179 : case DW_OP_lit0 ... DW_OP_lit31:
180 114 : if (! push (op->atom - DW_OP_lit0))
181 : {
182 0 : free (stack.addrs);
183 10 : return false;
184 : }
185 2733 : break;
186 : case DW_OP_addr:
187 0 : if (! push (op->number + bias))
188 : {
189 0 : free (stack.addrs);
190 0 : return false;
191 : }
192 : break;
193 : case DW_OP_GNU_encoded_addr:
194 : /* Missing support in the rest of elfutils. */
195 0 : __libdwfl_seterrno (DWFL_E_UNSUPPORTED_DWARF);
196 0 : return false;
197 : case DW_OP_const1u:
198 : case DW_OP_const1s:
199 : case DW_OP_const2u:
200 : case DW_OP_const2s:
201 : case DW_OP_const4u:
202 : case DW_OP_const4s:
203 : case DW_OP_const8u:
204 : case DW_OP_const8s:
205 : case DW_OP_constu:
206 : case DW_OP_consts:
207 35 : if (! push (op->number))
208 : {
209 0 : free (stack.addrs);
210 0 : return false;
211 : }
212 : break;
213 : case DW_OP_reg0 ... DW_OP_reg31:
214 0 : if (! state_get_reg (state, op->atom - DW_OP_reg0, &val1)
215 0 : || ! push (val1))
216 : {
217 0 : free (stack.addrs);
218 0 : return false;
219 : }
220 : break;
221 : case DW_OP_regx:
222 72 : if (! state_get_reg (state, op->number, &val1) || ! push (val1))
223 : {
224 0 : free (stack.addrs);
225 0 : return false;
226 : }
227 : break;
228 : case DW_OP_breg0 ... DW_OP_breg31:
229 0 : if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1))
230 : {
231 0 : free (stack.addrs);
232 0 : return false;
233 : }
234 0 : val1 += op->number;
235 0 : if (! push (val1))
236 : {
237 0 : free (stack.addrs);
238 0 : return false;
239 : }
240 : break;
241 : case DW_OP_bregx:
242 785 : if (! state_get_reg (state, op->number, &val1))
243 : {
244 5 : free (stack.addrs);
245 5 : return false;
246 : }
247 780 : val1 += op->number2;
248 780 : if (! push (val1))
249 : {
250 0 : free (stack.addrs);
251 0 : return false;
252 : }
253 : break;
254 : case DW_OP_dup:
255 2 : if (! pop (&val1) || ! push (val1) || ! push (val1))
256 : {
257 0 : free (stack.addrs);
258 0 : return false;
259 : }
260 : break;
261 : case DW_OP_drop:
262 2 : if (! pop (&val1))
263 : {
264 0 : free (stack.addrs);
265 0 : return false;
266 : }
267 : break;
268 : case DW_OP_pick:
269 2 : if (stack.used <= op->number)
270 : {
271 0 : free (stack.addrs);
272 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
273 0 : return false;
274 : }
275 2 : if (! push (stack.addrs[stack.used - 1 - op->number]))
276 : {
277 0 : free (stack.addrs);
278 0 : return false;
279 : }
280 : break;
281 : case DW_OP_over:
282 21 : if (! pop (&val1) || ! pop (&val2)
283 7 : || ! push (val2) || ! push (val1) || ! push (val2))
284 : {
285 0 : free (stack.addrs);
286 0 : return false;
287 : }
288 : break;
289 : case DW_OP_swap:
290 3 : if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
291 : {
292 0 : free (stack.addrs);
293 0 : return false;
294 : }
295 : break;
296 : case DW_OP_rot:
297 : {
298 : Dwarf_Addr val3;
299 4 : if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
300 1 : || ! push (val1) || ! push (val3) || ! push (val2))
301 : {
302 0 : free (stack.addrs);
303 : return false;
304 : }
305 : }
306 : break;
307 : case DW_OP_deref:
308 : case DW_OP_deref_size:
309 0 : if (process->callbacks->memory_read == NULL)
310 : {
311 0 : free (stack.addrs);
312 0 : __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
313 0 : return false;
314 : }
315 0 : if (! pop (&val1)
316 0 : || ! process->callbacks->memory_read (process->dwfl, val1, &val1,
317 : process->callbacks_arg))
318 : {
319 0 : free (stack.addrs);
320 0 : return false;
321 : }
322 0 : if (op->atom == DW_OP_deref_size)
323 : {
324 0 : const int elfclass = frame->cache->e_ident[EI_CLASS];
325 0 : const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
326 0 : if (op->number > addr_bytes)
327 : {
328 0 : free (stack.addrs);
329 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
330 0 : return false;
331 : }
332 : #if BYTE_ORDER == BIG_ENDIAN
333 : if (op->number == 0)
334 : val1 = 0;
335 : else
336 : val1 >>= (addr_bytes - op->number) * 8;
337 : #else
338 0 : if (op->number < 8)
339 0 : val1 &= (1 << (op->number * 8)) - 1;
340 : #endif
341 : }
342 0 : if (! push (val1))
343 : {
344 0 : free (stack.addrs);
345 0 : return false;
346 : }
347 : break;
348 : #define UNOP(atom, expr) \
349 : case atom: \
350 : if (! pop (&val1) || ! push (expr)) \
351 : { \
352 : free (stack.addrs); \
353 : return false; \
354 : } \
355 : break;
356 4 : UNOP (DW_OP_abs, llabs ((int64_t) val1))
357 6 : UNOP (DW_OP_neg, -(int64_t) val1)
358 2 : UNOP (DW_OP_not, ~val1)
359 : #undef UNOP
360 : case DW_OP_plus_uconst:
361 1232 : if (! pop (&val1) || ! push (val1 + op->number))
362 : {
363 0 : free (stack.addrs);
364 0 : return false;
365 : }
366 : break;
367 : #define BINOP(atom, op) \
368 : case atom: \
369 : if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2)) \
370 : { \
371 : free (stack.addrs); \
372 : return false; \
373 : } \
374 : break;
375 : #define BINOP_SIGNED(atom, op) \
376 : case atom: \
377 : if (! pop (&val2) || ! pop (&val1) \
378 : || ! push ((int64_t) val1 op (int64_t) val2)) \
379 : { \
380 : free (stack.addrs); \
381 : return false; \
382 : } \
383 : break;
384 6 : BINOP (DW_OP_and, &)
385 : case DW_OP_div:
386 15 : if (! pop (&val2) || ! pop (&val1))
387 : {
388 0 : free (stack.addrs);
389 0 : return false;
390 : }
391 5 : if (val2 == 0)
392 : {
393 0 : free (stack.addrs);
394 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
395 0 : return false;
396 : }
397 5 : if (! push ((int64_t) val1 / (int64_t) val2))
398 : {
399 0 : free (stack.addrs);
400 0 : return false;
401 : }
402 : break;
403 15 : BINOP (DW_OP_minus, -)
404 : case DW_OP_mod:
405 9 : if (! pop (&val2) || ! pop (&val1))
406 : {
407 0 : free (stack.addrs);
408 0 : return false;
409 : }
410 3 : if (val2 == 0)
411 : {
412 0 : free (stack.addrs);
413 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
414 0 : return false;
415 : }
416 3 : if (! push (val1 % val2))
417 : {
418 0 : free (stack.addrs);
419 0 : return false;
420 : }
421 : break;
422 12 : BINOP (DW_OP_mul, *)
423 3 : BINOP (DW_OP_or, |)
424 6 : BINOP (DW_OP_plus, +)
425 3 : BINOP (DW_OP_shl, <<)
426 6 : BINOP (DW_OP_shr, >>)
427 6 : BINOP_SIGNED (DW_OP_shra, >>)
428 3 : BINOP (DW_OP_xor, ^)
429 9 : BINOP_SIGNED (DW_OP_le, <=)
430 9 : BINOP_SIGNED (DW_OP_ge, >=)
431 156 : BINOP_SIGNED (DW_OP_eq, ==)
432 12 : BINOP_SIGNED (DW_OP_lt, <)
433 12 : BINOP_SIGNED (DW_OP_gt, >)
434 9 : BINOP_SIGNED (DW_OP_ne, !=)
435 : #undef BINOP
436 : #undef BINOP_SIGNED
437 : case DW_OP_bra:
438 122 : if (! pop (&val1))
439 : {
440 0 : free (stack.addrs);
441 0 : return false;
442 : }
443 61 : if (val1 == 0)
444 : break;
445 : FALLTHROUGH;
446 : case DW_OP_skip:;
447 61 : Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
448 61 : const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops,
449 : sizeof (*ops), bra_compar);
450 61 : if (found == NULL)
451 : {
452 0 : free (stack.addrs);
453 : /* PPC32 vDSO has such invalid operations. */
454 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
455 0 : return false;
456 : }
457 : /* Undo the 'for' statement increment. */
458 61 : op = found - 1;
459 61 : break;
460 : case DW_OP_nop:
461 : break;
462 : /* DW_OP_* not listed in libgcc/unwind-dw2.c execute_stack_op: */
463 : case DW_OP_call_frame_cfa:;
464 : // Not used by CFI itself but it is synthetized by elfutils internation.
465 : Dwarf_Op *cfa_ops;
466 : size_t cfa_nops;
467 : Dwarf_Addr cfa;
468 785 : if (frame == NULL
469 785 : || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
470 785 : || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias)
471 780 : || ! push (cfa))
472 : {
473 5 : __libdwfl_seterrno (DWFL_E_LIBDW);
474 5 : free (stack.addrs);
475 5 : return false;
476 : }
477 : is_location = true;
478 : break;
479 : case DW_OP_stack_value:
480 : // Not used by CFI itself but it is synthetized by elfutils internation.
481 157 : is_location = false;
482 157 : break;
483 : default:
484 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
485 0 : return false;
486 : }
487 : }
488 3264 : if (! pop (result))
489 : {
490 0 : free (stack.addrs);
491 0 : return false;
492 : }
493 1632 : free (stack.addrs);
494 1632 : if (is_location)
495 : {
496 623 : if (process->callbacks->memory_read == NULL)
497 : {
498 0 : __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
499 0 : return false;
500 : }
501 623 : if (! process->callbacks->memory_read (process->dwfl, *result, result,
502 : process->callbacks_arg))
503 : return false;
504 : }
505 : return true;
506 : #undef push
507 : #undef pop
508 : }
509 :
510 : static Dwfl_Frame *
511 251 : new_unwound (Dwfl_Frame *state)
512 : {
513 251 : assert (state->unwound == NULL);
514 251 : Dwfl_Thread *thread = state->thread;
515 251 : Dwfl_Process *process = thread->process;
516 251 : Ebl *ebl = process->ebl;
517 251 : size_t nregs = ebl_frame_nregs (ebl);
518 251 : assert (nregs > 0);
519 : Dwfl_Frame *unwound;
520 251 : unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
521 251 : if (unlikely (unwound == NULL))
522 : return NULL;
523 251 : state->unwound = unwound;
524 251 : unwound->thread = thread;
525 251 : unwound->unwound = NULL;
526 251 : unwound->signal_frame = false;
527 251 : unwound->initial_frame = false;
528 251 : unwound->pc_state = DWFL_FRAME_STATE_ERROR;
529 251 : memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
530 251 : return unwound;
531 : }
532 :
533 : /* The logic is to call __libdwfl_seterrno for any CFI bytecode interpretation
534 : error so one can easily catch the problem with a debugger. Still there are
535 : archs with invalid CFI for some registers where the registers are never used
536 : later. Therefore we continue unwinding leaving the registers undefined. */
537 :
538 : static void
539 276 : handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
540 : {
541 : Dwarf_Frame *frame;
542 276 : if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0)
543 : {
544 91 : __libdwfl_seterrno (DWFL_E_LIBDW);
545 91 : return;
546 : }
547 :
548 185 : Dwfl_Frame *unwound = new_unwound (state);
549 185 : if (unwound == NULL)
550 : {
551 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
552 0 : return;
553 : }
554 :
555 185 : unwound->signal_frame = frame->fde->cie->signal_frame;
556 185 : Dwfl_Thread *thread = state->thread;
557 185 : Dwfl_Process *process = thread->process;
558 185 : Ebl *ebl = process->ebl;
559 185 : size_t nregs = ebl_frame_nregs (ebl);
560 185 : assert (nregs > 0);
561 :
562 : /* The return register is special for setting the unwound->pc_state. */
563 185 : unsigned ra = frame->fde->cie->return_address_register;
564 185 : bool ra_set = false;
565 185 : ebl_dwarf_to_regno (ebl, &ra);
566 :
567 6734 : for (unsigned regno = 0; regno < nregs; regno++)
568 : {
569 : Dwarf_Op reg_ops_mem[3], *reg_ops;
570 : size_t reg_nops;
571 6549 : if (dwarf_frame_register (frame, regno, reg_ops_mem, ®_ops,
572 : ®_nops) != 0)
573 : {
574 0 : __libdwfl_seterrno (DWFL_E_LIBDW);
575 4660 : continue;
576 : }
577 : Dwarf_Addr regval;
578 6549 : if (reg_nops == 0)
579 : {
580 5692 : if (reg_ops == reg_ops_mem)
581 : {
582 : /* REGNO is undefined. */
583 3770 : if (regno == ra)
584 17 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
585 3770 : continue;
586 : }
587 1922 : else if (reg_ops == NULL)
588 : {
589 : /* REGNO is same-value. */
590 1922 : if (! state_get_reg (state, regno, ®val))
591 879 : continue;
592 : }
593 : else
594 : {
595 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
596 0 : continue;
597 : }
598 : }
599 857 : else if (! expr_eval (state, frame, reg_ops, reg_nops, ®val, bias))
600 : {
601 : /* PPC32 vDSO has various invalid operations, ignore them. The
602 : register will look as unset causing an error later, if used.
603 : But PPC32 does not use such registers. */
604 11 : continue;
605 : }
606 :
607 : /* Some architectures encode some extra info in the return address. */
608 1889 : if (regno == frame->fde->cie->return_address_register)
609 166 : regval &= ebl_func_addr_mask (ebl);
610 :
611 : /* This is another strange PPC[64] case. There are two
612 : registers numbers that can represent the same DWARF return
613 : register number. We only want one to actually set the return
614 : register value. But we always want to override the value if
615 : the register is the actual CIE return address register. */
616 1889 : if (ra_set && regno != frame->fde->cie->return_address_register)
617 : {
618 209 : unsigned r = regno;
619 209 : if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
620 0 : continue;
621 : }
622 :
623 1889 : if (! __libdwfl_frame_reg_set (unwound, regno, regval))
624 : {
625 0 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
626 0 : continue;
627 : }
628 1889 : else if (! ra_set)
629 : {
630 1680 : unsigned r = regno;
631 1680 : if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
632 166 : ra_set = true;
633 : }
634 : }
635 185 : if (unwound->pc_state == DWFL_FRAME_STATE_ERROR)
636 : {
637 336 : if (__libdwfl_frame_reg_get (unwound,
638 168 : frame->fde->cie->return_address_register,
639 : &unwound->pc))
640 : {
641 : /* PPC32 __libc_start_main properly CFI-unwinds PC as zero.
642 : Currently none of the archs supported for unwinding have
643 : zero as a valid PC. */
644 166 : if (unwound->pc == 0)
645 1 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
646 : else
647 : {
648 165 : unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
649 : /* In SPARC the return address register actually contains
650 : the address of the call instruction instead of the return
651 : address. Therefore we add here an offset defined by the
652 : backend. Most likely 0. */
653 165 : unwound->pc += ebl_ra_offset (ebl);
654 : }
655 : }
656 : else
657 : {
658 : /* We couldn't set the return register, either it was bogus,
659 : or the return pc is undefined, maybe end of call stack. */
660 2 : unsigned pcreg = frame->fde->cie->return_address_register;
661 2 : if (! ebl_dwarf_to_regno (ebl, &pcreg)
662 2 : || pcreg >= ebl_frame_nregs (ebl))
663 0 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
664 : else
665 2 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
666 : }
667 : }
668 185 : free (frame);
669 : }
670 :
671 : static bool
672 93 : setfunc (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg)
673 : {
674 93 : Dwfl_Frame *state = arg;
675 93 : Dwfl_Frame *unwound = state->unwound;
676 93 : if (firstreg < 0)
677 : {
678 29 : assert (firstreg == -1);
679 29 : assert (nregs == 1);
680 29 : assert (unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
681 29 : unwound->pc = *regs;
682 29 : unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
683 29 : return true;
684 : }
685 133 : while (nregs--)
686 69 : if (! __libdwfl_frame_reg_set (unwound, firstreg++, *regs++))
687 : return false;
688 : return true;
689 : }
690 :
691 : static bool
692 89 : getfunc (int firstreg, unsigned nregs, Dwarf_Word *regs, void *arg)
693 : {
694 89 : Dwfl_Frame *state = arg;
695 89 : assert (firstreg >= 0);
696 191 : while (nregs--)
697 102 : if (! __libdwfl_frame_reg_get (state, firstreg++, regs++))
698 : return false;
699 : return true;
700 : }
701 :
702 : static bool
703 64 : readfunc (Dwarf_Addr addr, Dwarf_Word *datap, void *arg)
704 : {
705 64 : Dwfl_Frame *state = arg;
706 64 : Dwfl_Thread *thread = state->thread;
707 64 : Dwfl_Process *process = thread->process;
708 64 : return process->callbacks->memory_read (process->dwfl, addr, datap,
709 : process->callbacks_arg);
710 : }
711 :
712 : void
713 : internal_function
714 407 : __libdwfl_frame_unwind (Dwfl_Frame *state)
715 : {
716 407 : if (state->unwound)
717 380 : return;
718 : /* Do not ask dwfl_frame_pc for ISACTIVATION, it would try to unwind STATE
719 : which would deadlock us. */
720 : Dwarf_Addr pc;
721 251 : bool ok = INTUSE(dwfl_frame_pc) (state, &pc, NULL);
722 251 : assert (ok);
723 : /* Check whether this is the initial frame or a signal frame.
724 : Then we need to unwind from the original, unadjusted PC. */
725 251 : if (! state->initial_frame && ! state->signal_frame)
726 204 : pc--;
727 251 : Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (state->thread->process->dwfl, pc);
728 251 : if (mod == NULL)
729 1 : __libdwfl_seterrno (DWFL_E_NO_DWARF);
730 : else
731 : {
732 : Dwarf_Addr bias;
733 250 : Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias);
734 250 : if (cfi_eh)
735 : {
736 240 : handle_cfi (state, pc - bias, cfi_eh, bias);
737 240 : if (state->unwound)
738 185 : return;
739 : }
740 82 : Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias);
741 82 : if (cfi_dwarf)
742 : {
743 36 : handle_cfi (state, pc - bias, cfi_dwarf, bias);
744 36 : if (state->unwound)
745 : return;
746 : }
747 : }
748 66 : assert (state->unwound == NULL);
749 66 : Dwfl_Thread *thread = state->thread;
750 66 : Dwfl_Process *process = thread->process;
751 66 : Ebl *ebl = process->ebl;
752 66 : if (new_unwound (state) == NULL)
753 : {
754 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
755 0 : return;
756 : }
757 66 : state->unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
758 : // &Dwfl_Frame.signal_frame cannot be passed as it is a bitfield.
759 66 : bool signal_frame = false;
760 66 : if (! ebl_unwind (ebl, pc, setfunc, getfunc, readfunc, state, &signal_frame))
761 : {
762 : // Discard the unwind attempt. During next __libdwfl_frame_unwind call
763 : // we may have for example the appropriate Dwfl_Module already mapped.
764 39 : assert (state->unwound->unwound == NULL);
765 39 : free (state->unwound);
766 39 : state->unwound = NULL;
767 : // __libdwfl_seterrno has been called above.
768 39 : return;
769 : }
770 27 : assert (state->unwound->pc_state == DWFL_FRAME_STATE_PC_SET);
771 27 : state->unwound->signal_frame = signal_frame;
772 : }
|