• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
__libdwfl_frame_reg_get(Dwfl_Frame * state,unsigned regno,Dwarf_Addr * val)48 __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
49 {
50   Ebl *ebl = state->thread->process->ebl;
51   if (! ebl_dwarf_to_regno (ebl, &regno))
52     return false;
53   if (regno >= ebl_frame_nregs (ebl))
54     return false;
55   if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
56        & ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
57     return false;
58   if (val)
59     *val = state->regs[regno];
60   return true;
61 }
62 
63 bool
64 internal_function
__libdwfl_frame_reg_set(Dwfl_Frame * state,unsigned regno,Dwarf_Addr val)65 __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val)
66 {
67   Ebl *ebl = state->thread->process->ebl;
68   if (! ebl_dwarf_to_regno (ebl, &regno))
69     return false;
70   if (regno >= ebl_frame_nregs (ebl))
71     return false;
72   /* For example i386 user_regs_struct has signed fields.  */
73   if (ebl_get_elfclass (ebl) == ELFCLASS32)
74     val &= 0xffffffff;
75   state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
76 		((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)));
77   state->regs[regno] = val;
78   return true;
79 }
80 
81 static bool
state_get_reg(Dwfl_Frame * state,unsigned regno,Dwarf_Addr * val)82 state_get_reg (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
83 {
84   if (! __libdwfl_frame_reg_get (state, regno, val))
85     {
86       __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
87       return false;
88     }
89   return true;
90 }
91 
92 static int
bra_compar(const void * key_voidp,const void * elem_voidp)93 bra_compar (const void *key_voidp, const void *elem_voidp)
94 {
95   Dwarf_Word offset = (uintptr_t) key_voidp;
96   const Dwarf_Op *op = elem_voidp;
97   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
do_push(struct eval_stack * stack,Dwarf_Addr val)107 do_push (struct eval_stack *stack, Dwarf_Addr val)
108 {
109   if (stack->used >= DWARF_EXPR_STACK_MAX)
110     {
111       __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
112       return false;
113     }
114   if (stack->used == stack->allocated)
115     {
116       stack->allocated = MAX (stack->allocated * 2, 32);
117       Dwarf_Addr *new_addrs;
118       new_addrs = realloc (stack->addrs,
119 			   stack->allocated * sizeof (*stack->addrs));
120       if (new_addrs == NULL)
121         {
122           __libdwfl_seterrno (DWFL_E_NOMEM);
123           return false;
124         }
125       stack->addrs = new_addrs;
126     }
127   stack->addrs[stack->used++] = val;
128   return true;
129 }
130 
131 static bool
do_pop(struct eval_stack * stack,Dwarf_Addr * val)132 do_pop (struct eval_stack *stack, Dwarf_Addr *val)
133 {
134   if (stack->used == 0)
135     {
136       __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
137       return false;
138     }
139   *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
expr_eval(Dwfl_Frame * state,Dwarf_Frame * frame,const Dwarf_Op * ops,size_t nops,Dwarf_Addr * result,Dwarf_Addr bias)147 expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
148 	   size_t nops, Dwarf_Addr *result, Dwarf_Addr bias)
149 {
150   Dwfl_Process *process = state->thread->process;
151   if (nops == 0)
152     {
153       __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
154       return false;
155     }
156   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   bool is_location = false;
168   size_t steps_count = 0;
169   for (const Dwarf_Op *op = ops; op < ops + nops; op++)
170     {
171       if (++steps_count > DWARF_EXPR_STEPS_MAX)
172 	{
173 	  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
174 	  return false;
175 	}
176       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 	  if (! push (op->atom - DW_OP_lit0))
181 	    {
182 	      free (stack.addrs);
183 	      return false;
184 	    }
185 	  break;
186 	case DW_OP_addr:
187 	  if (! push (op->number + bias))
188 	    {
189 	      free (stack.addrs);
190 	      return false;
191 	    }
192 	  break;
193 	case DW_OP_GNU_encoded_addr:
194 	  /* Missing support in the rest of elfutils.  */
195 	  __libdwfl_seterrno (DWFL_E_UNSUPPORTED_DWARF);
196 	  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 	  if (! push (op->number))
208 	    {
209 	      free (stack.addrs);
210 	      return false;
211 	    }
212 	  break;
213 	case DW_OP_reg0 ... DW_OP_reg31:
214 	  if (! state_get_reg (state, op->atom - DW_OP_reg0, &val1)
215 	      || ! push (val1))
216 	    {
217 	      free (stack.addrs);
218 	      return false;
219 	    }
220 	  break;
221 	case DW_OP_regx:
222 	  if (! state_get_reg (state, op->number, &val1) || ! push (val1))
223 	    {
224 	      free (stack.addrs);
225 	      return false;
226 	    }
227 	  break;
228 	case DW_OP_breg0 ... DW_OP_breg31:
229 	  if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1))
230 	    {
231 	      free (stack.addrs);
232 	      return false;
233 	    }
234 	  val1 += op->number;
235 	  if (! push (val1))
236 	    {
237 	      free (stack.addrs);
238 	      return false;
239 	    }
240 	  break;
241 	case DW_OP_bregx:
242 	  if (! state_get_reg (state, op->number, &val1))
243 	    {
244 	      free (stack.addrs);
245 	      return false;
246 	    }
247 	  val1 += op->number2;
248 	  if (! push (val1))
249 	    {
250 	      free (stack.addrs);
251 	      return false;
252 	    }
253 	  break;
254 	case DW_OP_dup:
255 	  if (! pop (&val1) || ! push (val1) || ! push (val1))
256 	    {
257 	      free (stack.addrs);
258 	      return false;
259 	    }
260 	  break;
261 	case DW_OP_drop:
262 	  if (! pop (&val1))
263 	    {
264 	      free (stack.addrs);
265 	      return false;
266 	    }
267 	  break;
268 	case DW_OP_pick:
269 	  if (stack.used <= op->number)
270 	    {
271 	      free (stack.addrs);
272 	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
273 	      return false;
274 	    }
275 	  if (! push (stack.addrs[stack.used - 1 - op->number]))
276 	    {
277 	      free (stack.addrs);
278 	      return false;
279 	    }
280 	  break;
281 	case DW_OP_over:
282 	  if (! pop (&val1) || ! pop (&val2)
283 	      || ! push (val2) || ! push (val1) || ! push (val2))
284 	    {
285 	      free (stack.addrs);
286 	      return false;
287 	    }
288 	  break;
289 	case DW_OP_swap:
290 	  if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
291 	    {
292 	      free (stack.addrs);
293 	      return false;
294 	    }
295 	  break;
296 	case DW_OP_rot:
297 	  {
298 	    Dwarf_Addr val3;
299 	    if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
300 		|| ! push (val1) || ! push (val3) || ! push (val2))
301 	      {
302 		free (stack.addrs);
303 		return false;
304 	      }
305 	  }
306 	  break;
307 	case DW_OP_deref:
308 	case DW_OP_deref_size:
309 	  if (process->callbacks->memory_read == NULL)
310 	    {
311 	      free (stack.addrs);
312 	      __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
313 	      return false;
314 	    }
315 	  if (! pop (&val1)
316 	      || ! process->callbacks->memory_read (process->dwfl, val1, &val1,
317 						    process->callbacks_arg))
318 	    {
319 	      free (stack.addrs);
320 	      return false;
321 	    }
322 	  if (op->atom == DW_OP_deref_size)
323 	    {
324 	      const int elfclass = frame->cache->e_ident[EI_CLASS];
325 	      const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
326 	      if (op->number > addr_bytes)
327 		{
328 		  free (stack.addrs);
329 		  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
330 		  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 	      if (op->number < 8)
339 		val1 &= (1 << (op->number * 8)) - 1;
340 #endif
341 	    }
342 	  if (! push (val1))
343 	    {
344 	      free (stack.addrs);
345 	      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 	UNOP (DW_OP_abs, llabs ((int64_t) val1))
357 	UNOP (DW_OP_neg, -(int64_t) val1)
358 	UNOP (DW_OP_not, ~val1)
359 #undef UNOP
360 	case DW_OP_plus_uconst:
361 	  if (! pop (&val1) || ! push (val1 + op->number))
362 	    {
363 	      free (stack.addrs);
364 	      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 	BINOP (DW_OP_and, &)
385 	case DW_OP_div:
386 	  if (! pop (&val2) || ! pop (&val1))
387 	    {
388 	      free (stack.addrs);
389 	      return false;
390 	    }
391 	  if (val2 == 0)
392 	    {
393 	      free (stack.addrs);
394 	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
395 	      return false;
396 	    }
397 	  if (! push ((int64_t) val1 / (int64_t) val2))
398 	    {
399 	      free (stack.addrs);
400 	      return false;
401 	    }
402 	  break;
403 	BINOP (DW_OP_minus, -)
404 	case DW_OP_mod:
405 	  if (! pop (&val2) || ! pop (&val1))
406 	    {
407 	      free (stack.addrs);
408 	      return false;
409 	    }
410 	  if (val2 == 0)
411 	    {
412 	      free (stack.addrs);
413 	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
414 	      return false;
415 	    }
416 	  if (! push (val1 % val2))
417 	    {
418 	      free (stack.addrs);
419 	      return false;
420 	    }
421 	  break;
422 	BINOP (DW_OP_mul, *)
423 	BINOP (DW_OP_or, |)
424 	BINOP (DW_OP_plus, +)
425 	BINOP (DW_OP_shl, <<)
426 	BINOP (DW_OP_shr, >>)
427 	BINOP_SIGNED (DW_OP_shra, >>)
428 	BINOP (DW_OP_xor, ^)
429 	BINOP_SIGNED (DW_OP_le, <=)
430 	BINOP_SIGNED (DW_OP_ge, >=)
431 	BINOP_SIGNED (DW_OP_eq, ==)
432 	BINOP_SIGNED (DW_OP_lt, <)
433 	BINOP_SIGNED (DW_OP_gt, >)
434 	BINOP_SIGNED (DW_OP_ne, !=)
435 #undef BINOP
436 #undef BINOP_SIGNED
437 	case DW_OP_bra:
438 	  if (! pop (&val1))
439 	    {
440 	      free (stack.addrs);
441 	      return false;
442 	    }
443 	  if (val1 == 0)
444 	    break;
445 	  FALLTHROUGH;
446 	case DW_OP_skip:;
447 	  Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
448 	  const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops,
449 					   sizeof (*ops), bra_compar);
450 	  if (found == NULL)
451 	    {
452 	      free (stack.addrs);
453 	      /* PPC32 vDSO has such invalid operations.  */
454 	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
455 	      return false;
456 	    }
457 	  /* Undo the 'for' statement increment.  */
458 	  op = found - 1;
459 	  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 	  if (frame == NULL
469 	      || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
470 	      || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias)
471 	      || ! push (cfa))
472 	    {
473 	      __libdwfl_seterrno (DWFL_E_LIBDW);
474 	      free (stack.addrs);
475 	      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 	  is_location = false;
482 	  break;
483 	default:
484 	  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
485 	  return false;
486       }
487     }
488   if (! pop (result))
489     {
490       free (stack.addrs);
491       return false;
492     }
493   free (stack.addrs);
494   if (is_location)
495     {
496       if (process->callbacks->memory_read == NULL)
497 	{
498 	  __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
499 	  return false;
500 	}
501       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 *
new_unwound(Dwfl_Frame * state)511 new_unwound (Dwfl_Frame *state)
512 {
513   assert (state->unwound == NULL);
514   Dwfl_Thread *thread = state->thread;
515   Dwfl_Process *process = thread->process;
516   Ebl *ebl = process->ebl;
517   size_t nregs = ebl_frame_nregs (ebl);
518   assert (nregs > 0);
519   Dwfl_Frame *unwound;
520   unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
521   if (unlikely (unwound == NULL))
522     return NULL;
523   state->unwound = unwound;
524   unwound->thread = thread;
525   unwound->unwound = NULL;
526   unwound->signal_frame = false;
527   unwound->initial_frame = false;
528   unwound->pc_state = DWFL_FRAME_STATE_ERROR;
529   memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
530   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
handle_cfi(Dwfl_Frame * state,Dwarf_Addr pc,Dwarf_CFI * cfi,Dwarf_Addr bias)539 handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
540 {
541   Dwarf_Frame *frame;
542   if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0)
543     {
544       __libdwfl_seterrno (DWFL_E_LIBDW);
545       return;
546     }
547 
548   Dwfl_Frame *unwound = new_unwound (state);
549   if (unwound == NULL)
550     {
551       __libdwfl_seterrno (DWFL_E_NOMEM);
552       return;
553     }
554 
555   unwound->signal_frame = frame->fde->cie->signal_frame;
556   Dwfl_Thread *thread = state->thread;
557   Dwfl_Process *process = thread->process;
558   Ebl *ebl = process->ebl;
559   size_t nregs = ebl_frame_nregs (ebl);
560   assert (nregs > 0);
561 
562   /* The return register is special for setting the unwound->pc_state.  */
563   unsigned ra = frame->fde->cie->return_address_register;
564   bool ra_set = false;
565   ebl_dwarf_to_regno (ebl, &ra);
566 
567   for (unsigned regno = 0; regno < nregs; regno++)
568     {
569       Dwarf_Op reg_ops_mem[3], *reg_ops;
570       size_t reg_nops;
571       if (dwarf_frame_register (frame, regno, reg_ops_mem, &reg_ops,
572 				&reg_nops) != 0)
573 	{
574 	  __libdwfl_seterrno (DWFL_E_LIBDW);
575 	  continue;
576 	}
577       Dwarf_Addr regval;
578       if (reg_nops == 0)
579 	{
580 	  if (reg_ops == reg_ops_mem)
581 	    {
582 	      /* REGNO is undefined.  */
583 	      if (regno == ra)
584 		unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
585 	      continue;
586 	    }
587 	  else if (reg_ops == NULL)
588 	    {
589 	      /* REGNO is same-value.  */
590 	      if (! state_get_reg (state, regno, &regval))
591 		continue;
592 	    }
593 	  else
594 	    {
595 	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
596 	      continue;
597 	    }
598 	}
599       else if (! expr_eval (state, frame, reg_ops, reg_nops, &regval, 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 	  continue;
605 	}
606 
607       /* Some architectures encode some extra info in the return address.  */
608       if (regno == frame->fde->cie->return_address_register)
609 	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       if (ra_set && regno != frame->fde->cie->return_address_register)
617 	{
618 	  unsigned r = regno;
619 	  if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
620 	    continue;
621 	}
622 
623       if (! __libdwfl_frame_reg_set (unwound, regno, regval))
624 	{
625 	  __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
626 	  continue;
627 	}
628       else if (! ra_set)
629 	{
630 	  unsigned r = regno;
631           if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
632 	    ra_set = true;
633 	}
634     }
635   if (unwound->pc_state == DWFL_FRAME_STATE_ERROR)
636     {
637       if (__libdwfl_frame_reg_get (unwound,
638 				   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 	  if (unwound->pc == 0)
645 	    unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
646 	  else
647 	    {
648 	      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 	      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 	  unsigned pcreg = frame->fde->cie->return_address_register;
661 	  if (! ebl_dwarf_to_regno (ebl, &pcreg)
662 	      || pcreg >= ebl_frame_nregs (ebl))
663 	    __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
664 	  else
665 	    unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
666 	}
667     }
668   free (frame);
669 }
670 
671 static bool
setfunc(int firstreg,unsigned nregs,const Dwarf_Word * regs,void * arg)672 setfunc (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg)
673 {
674   Dwfl_Frame *state = arg;
675   Dwfl_Frame *unwound = state->unwound;
676   if (firstreg < 0)
677     {
678       assert (firstreg == -1);
679       assert (nregs == 1);
680       assert (unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
681       unwound->pc = *regs;
682       unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
683       return true;
684     }
685   while (nregs--)
686     if (! __libdwfl_frame_reg_set (unwound, firstreg++, *regs++))
687       return false;
688   return true;
689 }
690 
691 static bool
getfunc(int firstreg,unsigned nregs,Dwarf_Word * regs,void * arg)692 getfunc (int firstreg, unsigned nregs, Dwarf_Word *regs, void *arg)
693 {
694   Dwfl_Frame *state = arg;
695   assert (firstreg >= 0);
696   while (nregs--)
697     if (! __libdwfl_frame_reg_get (state, firstreg++, regs++))
698       return false;
699   return true;
700 }
701 
702 static bool
readfunc(Dwarf_Addr addr,Dwarf_Word * datap,void * arg)703 readfunc (Dwarf_Addr addr, Dwarf_Word *datap, void *arg)
704 {
705   Dwfl_Frame *state = arg;
706   Dwfl_Thread *thread = state->thread;
707   Dwfl_Process *process = thread->process;
708   return process->callbacks->memory_read (process->dwfl, addr, datap,
709 					  process->callbacks_arg);
710 }
711 
712 void
713 internal_function
__libdwfl_frame_unwind(Dwfl_Frame * state)714 __libdwfl_frame_unwind (Dwfl_Frame *state)
715 {
716   if (state->unwound)
717     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   bool ok = INTUSE(dwfl_frame_pc) (state, &pc, NULL);
722   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   if (! state->initial_frame && ! state->signal_frame)
726     pc--;
727   Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (state->thread->process->dwfl, pc);
728   if (mod == NULL)
729     __libdwfl_seterrno (DWFL_E_NO_DWARF);
730   else
731     {
732       Dwarf_Addr bias;
733       Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias);
734       if (cfi_eh)
735 	{
736 	  handle_cfi (state, pc - bias, cfi_eh, bias);
737 	  if (state->unwound)
738 	    return;
739 	}
740       Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias);
741       if (cfi_dwarf)
742 	{
743 	  handle_cfi (state, pc - bias, cfi_dwarf, bias);
744 	  if (state->unwound)
745 	    return;
746 	}
747     }
748   assert (state->unwound == NULL);
749   Dwfl_Thread *thread = state->thread;
750   Dwfl_Process *process = thread->process;
751   Ebl *ebl = process->ebl;
752   if (new_unwound (state) == NULL)
753     {
754       __libdwfl_seterrno (DWFL_E_NOMEM);
755       return;
756     }
757   state->unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
758   // &Dwfl_Frame.signal_frame cannot be passed as it is a bitfield.
759   bool signal_frame = false;
760   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       assert (state->unwound->unwound == NULL);
765       free (state->unwound);
766       state->unwound = NULL;
767       // __libdwfl_seterrno has been called above.
768       return;
769     }
770   assert (state->unwound->pc_state == DWFL_FRAME_STATE_PC_SET);
771   state->unwound->signal_frame = signal_frame;
772 }
773