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