10b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* Get previous frame state for an existing frame state.
2c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard   Copyright (C) 2013, 2014 Red Hat, Inc.
30b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   This file is part of elfutils.
40b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
50b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   This file is free software; you can redistribute it and/or modify
60b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   it under the terms of either
70b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
80b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil     * the GNU Lesser General Public License as published by the Free
90b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil       Software Foundation; either version 3 of the License, or (at
100b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil       your option) any later version
110b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   or
130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil     * the GNU General Public License as published by the Free
150b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil       Software Foundation; either version 2 of the License, or (at
160b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil       your option) any later version
170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   or both in parallel, as here.
190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
200b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   elfutils is distributed in the hope that it will be useful, but
210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   WITHOUT ANY WARRANTY; without even the implied warranty of
220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
230b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   General Public License for more details.
240b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
250b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   You should have received copies of the GNU General Public License and
260b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   the GNU Lesser General Public License along with this program.  If
270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   not, see <http://www.gnu.org/licenses/>.  */
280b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#ifdef HAVE_CONFIG_H
300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# include <config.h>
310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif
320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include "cfi.h"
340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <stdlib.h>
350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include "libdwflP.h"
360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include "../libdw/dwarf.h"
370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <sys/ptrace.h>
380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* Maximum number of DWARF expression stack slots before returning an error.  */
400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#define DWARF_EXPR_STACK_MAX 0x100
410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* Maximum number of DWARF expression executed operations before returning an
430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   error.  */
440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#define DWARF_EXPR_STEPS_MAX 0x1000
450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#ifndef MAX
470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# define MAX(a, b) ((a) > (b) ? (a) : (b))
480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif
490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilbool
510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilinternal_function
520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil__libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Ebl *ebl = state->thread->process->ebl;
555cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil  if (! ebl_dwarf_to_regno (ebl, &regno))
565cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil    return false;
570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (regno >= ebl_frame_nregs (ebl))
580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
60740d1fe49758f28aad50b1d67b139a1564d73bbdMark Wielaard       & ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
610b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (val)
630b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    *val = state->regs[regno];
640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return true;
650b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
660b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
670b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilbool
680b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilinternal_function
690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil__libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val)
700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Ebl *ebl = state->thread->process->ebl;
725cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil  if (! ebl_dwarf_to_regno (ebl, &regno))
735cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil    return false;
740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (regno >= ebl_frame_nregs (ebl))
750b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  /* For example i386 user_regs_struct has signed fields.  */
770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (ebl_get_elfclass (ebl) == ELFCLASS32)
780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    val &= 0xffffffff;
790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
80740d1fe49758f28aad50b1d67b139a1564d73bbdMark Wielaard		((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)));
810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  state->regs[regno] = val;
820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return true;
830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstate_get_reg (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (! __libdwfl_frame_reg_get (state, regno, val))
890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return false;
920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return true;
940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic int
970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilbra_compar (const void *key_voidp, const void *elem_voidp)
980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwarf_Word offset = (uintptr_t) key_voidp;
1000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  const Dwarf_Op *op = elem_voidp;
1010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return (offset > op->offset) - (offset < op->offset);
1020b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
1030b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
104ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsiehstruct eval_stack {
105ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  Dwarf_Addr *addrs;
106ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  size_t used;
107ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  size_t allocated;
108ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh};
109ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh
110ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsiehstatic bool
111ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsiehdo_push (struct eval_stack *stack, Dwarf_Addr val)
112ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh{
113ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  if (stack->used >= DWARF_EXPR_STACK_MAX)
114ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh    {
115ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
116ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      return false;
117ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh    }
118ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  if (stack->used == stack->allocated)
119ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh    {
120ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      stack->allocated = MAX (stack->allocated * 2, 32);
121ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      Dwarf_Addr *new_addrs;
122ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      new_addrs = realloc (stack->addrs,
123ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh			   stack->allocated * sizeof (*stack->addrs));
124ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      if (new_addrs == NULL)
125ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh        {
126ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh          __libdwfl_seterrno (DWFL_E_NOMEM);
127ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh          return false;
128ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh        }
129ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      stack->addrs = new_addrs;
130ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh    }
131ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  stack->addrs[stack->used++] = val;
132ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  return true;
133ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh}
134ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh
135ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsiehstatic bool
136ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsiehdo_pop (struct eval_stack *stack, Dwarf_Addr *val)
137ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh{
138ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  if (stack->used == 0)
139ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh    {
140ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
141ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      return false;
142ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh    }
143ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  *val = stack->addrs[--stack->used];
144ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  return true;
145ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh}
146ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh
1470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* If FRAME is NULL is are computing CFI frame base.  In such case another
1480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   DW_OP_call_frame_cfa is no longer permitted.  */
1490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
1500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
1510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilexpr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
1520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	   size_t nops, Dwarf_Addr *result, Dwarf_Addr bias)
1530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
1540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Process *process = state->thread->process;
1550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (nops == 0)
1560b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
1580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return false;
1590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
160ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  struct eval_stack stack =
161ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh    {
162ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      .addrs = NULL,
163ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      .used = 0,
164ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      .allocated = 0
165ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh    };
1660b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
167ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh#define pop(x) do_pop(&stack, x)
168ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh#define push(x) do_push(&stack, x)
1690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
1700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwarf_Addr val1, val2;
1710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  bool is_location = false;
1720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  size_t steps_count = 0;
1730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  for (const Dwarf_Op *op = ops; op < ops + nops; op++)
1740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1750b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (++steps_count > DWARF_EXPR_STEPS_MAX)
1760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
1770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
1780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return false;
1790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
1800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      switch (op->atom)
1810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      {
1820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	/* DW_OP_* order matches libgcc/unwind-dw2.c execute_stack_op:  */
1830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_lit0 ... DW_OP_lit31:
1840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! push (op->atom - DW_OP_lit0))
1850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
186ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
1870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
1880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
1890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
1900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_addr:
1910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! push (op->number + bias))
1920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
193ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
1940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
1950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
1960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
1970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_GNU_encoded_addr:
1980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  /* Missing support in the rest of elfutils.  */
1990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_UNSUPPORTED_DWARF);
2000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return false;
2010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_const1u:
2020b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_const1s:
2030b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_const2u:
2040b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_const2s:
2050b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_const4u:
2060b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_const4s:
2070b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_const8u:
2080b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_const8s:
2090b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_constu:
2100b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_consts:
2110b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! push (op->number))
2120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
213ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2150b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2160b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_reg0 ... DW_OP_reg31:
2180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! state_get_reg (state, op->atom - DW_OP_reg0, &val1)
2190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      || ! push (val1))
2200b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
221ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2230b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2240b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2250b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_regx:
2260b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! state_get_reg (state, op->number, &val1) || ! push (val1))
2270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
228ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_breg0 ... DW_OP_breg31:
2330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1))
2340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
235ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  val1 += op->number;
2390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! push (val1))
2400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
241ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_bregx:
2460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! state_get_reg (state, op->number, &val1))
2470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
248ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  val1 += op->number2;
2520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! push (val1))
2530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
254ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2560b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_dup:
2590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val1) || ! push (val1) || ! push (val1))
2600b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
261ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2630b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2650b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_drop:
2660b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val1))
2670b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
268ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_pick:
273ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	  if (stack.used <= op->number)
2740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
275ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
2770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
279ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	  if (! push (stack.addrs[stack.used - 1 - op->number]))
2800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
281ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_over:
2860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val1) || ! pop (&val2)
2870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      || ! push (val2) || ! push (val1) || ! push (val2))
2880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
289ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
2930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_swap:
2940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
2950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
296ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
2970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
2980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
2990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
3000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_rot:
3010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  {
3020b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    Dwarf_Addr val3;
3030b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
3040b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		|| ! push (val1) || ! push (val3) || ! push (val2))
3050b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      {
306ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh		free (stack.addrs);
3070b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		return false;
3080b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      }
3090b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  }
3100b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
3110b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_deref:
3120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_deref_size:
3130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (process->callbacks->memory_read == NULL)
3140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
315ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
3160b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
3170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
3180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
3190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val1)
3200b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      || ! process->callbacks->memory_read (process->dwfl, val1, &val1,
3210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil						    process->callbacks_arg))
3220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
323ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
3240b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
3250b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
3260b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (op->atom == DW_OP_deref_size)
3270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
3280b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      const int elfclass = frame->cache->e_ident[EI_CLASS];
3290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
3300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      if (op->number > addr_bytes)
3310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		{
332ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh		  free (stack.addrs);
3330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
3340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		  return false;
3350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		}
3360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#if BYTE_ORDER == BIG_ENDIAN
3370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      if (op->number == 0)
3380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		val1 = 0;
3390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      else
3400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		val1 >>= (addr_bytes - op->number) * 8;
3410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#else
3420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      if (op->number < 8)
3430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		val1 &= (1 << (op->number * 8)) - 1;
3440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif
3450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
3460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! push (val1))
3470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
348ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
3490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
3500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
3510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
3520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#define UNOP(atom, expr)						\
3530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case atom:							\
3540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val1) || ! push (expr))				\
3550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {								\
356ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);					\
3570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;						\
3580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }								\
3590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
3604169187fe3abfda5b7df3eb39ab6bc15d08e13a1Chih-Hung Hsieh	UNOP (DW_OP_abs, llabs ((int64_t) val1))
3610b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	UNOP (DW_OP_neg, -(int64_t) val1)
3620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	UNOP (DW_OP_not, ~val1)
3630b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#undef UNOP
3640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_plus_uconst:
3650b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val1) || ! push (val1 + op->number))
3660b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
367ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
3680b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
3690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
3700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
3710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#define BINOP(atom, op)							\
3720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case atom:							\
3730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2))	\
3740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {								\
375ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);					\
3760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;						\
3770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }								\
3780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
3790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#define BINOP_SIGNED(atom, op)						\
3800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case atom:							\
3810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val2) || ! pop (&val1)				\
3820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      || ! push ((int64_t) val1 op (int64_t) val2))		\
3830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {								\
384ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);					\
3850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;						\
3860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }								\
3870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
3880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP (DW_OP_and, &)
3890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_div:
3900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val2) || ! pop (&val1))
3910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
392ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
3930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
3940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
3950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (val2 == 0)
3960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
397ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
3980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
3990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
4000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
4010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! push ((int64_t) val1 / (int64_t) val2))
4020b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
403ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
4040b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
4050b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
4060b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
4070b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP (DW_OP_minus, -)
4080b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_mod:
4090b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val2) || ! pop (&val1))
4100b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
411ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
4120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
4130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
4140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (val2 == 0)
4150b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
416ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
4170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
4180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
4190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
4200b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! push (val1 % val2))
4210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
422ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
4230b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
4240b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
4250b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
4260b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP (DW_OP_mul, *)
4270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP (DW_OP_or, |)
4280b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP (DW_OP_plus, +)
4290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP (DW_OP_shl, <<)
4300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP (DW_OP_shr, >>)
4310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP_SIGNED (DW_OP_shra, >>)
4320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP (DW_OP_xor, ^)
4330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP_SIGNED (DW_OP_le, <=)
4340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP_SIGNED (DW_OP_ge, >=)
4350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP_SIGNED (DW_OP_eq, ==)
4360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP_SIGNED (DW_OP_lt, <)
4370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP_SIGNED (DW_OP_gt, >)
4380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	BINOP_SIGNED (DW_OP_ne, !=)
4390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#undef BINOP
4400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#undef BINOP_SIGNED
4410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_bra:
4420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (! pop (&val1))
4430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
444ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
4450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
4460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
4470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (val1 == 0)
4480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    break;
4490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  /* FALLTHRU */
4500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_skip:;
4510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
4520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops,
4530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil					   sizeof (*ops), bra_compar);
4540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (found == NULL)
4550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
456ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
4570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      /* PPC32 vDSO has such invalid operations.  */
4580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
4590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
4600b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
4610b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  /* Undo the 'for' statement increment.  */
4620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  op = found - 1;
4630b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
4640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_nop:
4650b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
4660b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	/* DW_OP_* not listed in libgcc/unwind-dw2.c execute_stack_op:  */
4670b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_call_frame_cfa:;
4680b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  // Not used by CFI itself but it is synthetized by elfutils internation.
4690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  Dwarf_Op *cfa_ops;
4700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  size_t cfa_nops;
4710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  Dwarf_Addr cfa;
4720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (frame == NULL
4730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
4740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias)
4750b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      || ! push (cfa))
4760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
4770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_LIBDW);
478ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh	      free (stack.addrs);
4790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return false;
4800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
4810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  is_location = true;
4820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
4830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	case DW_OP_stack_value:
4840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  // Not used by CFI itself but it is synthetized by elfutils internation.
4850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  is_location = false;
4860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  break;
4870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	default:
4880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
4890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return false;
4900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      }
4910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
4920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (! pop (result))
4930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
494ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh      free (stack.addrs);
4950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return false;
4960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
497ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh  free (stack.addrs);
4980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (is_location)
4990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
5000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (process->callbacks->memory_read == NULL)
5010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
5020b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
5030b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return false;
5040b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
5050b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (! process->callbacks->memory_read (process->dwfl, *result, result,
5060b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil					     process->callbacks_arg))
5070b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	return false;
5080b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
5090b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return true;
510ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh#undef push
511ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798Chih-Hung Hsieh#undef pop
5120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
5130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
514c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvilstatic void
515c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvilnew_unwound (Dwfl_Frame *state)
516c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil{
517c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  assert (state->unwound == NULL);
518c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Thread *thread = state->thread;
519c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Process *process = thread->process;
520c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Ebl *ebl = process->ebl;
521c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  size_t nregs = ebl_frame_nregs (ebl);
522c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  assert (nregs > 0);
523c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Frame *unwound;
524c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
525c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  state->unwound = unwound;
526c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  unwound->thread = thread;
527c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  unwound->unwound = NULL;
528c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  unwound->signal_frame = false;
529c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  unwound->initial_frame = false;
530c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  unwound->pc_state = DWFL_FRAME_STATE_ERROR;
531c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
532c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil}
533c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil
5340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* The logic is to call __libdwfl_seterrno for any CFI bytecode interpretation
5350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   error so one can easily catch the problem with a debugger.  Still there are
5360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   archs with invalid CFI for some registers where the registers are never used
5370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   later.  Therefore we continue unwinding leaving the registers undefined.  */
5380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
5390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic void
5400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilhandle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
5410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
5420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwarf_Frame *frame;
5430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0)
5440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
5450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_LIBDW);
5460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return;
5470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
548c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  new_unwound (state);
549c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Frame *unwound = state->unwound;
550c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  unwound->signal_frame = frame->fde->cie->signal_frame;
5510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Thread *thread = state->thread;
5520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Process *process = thread->process;
5530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Ebl *ebl = process->ebl;
5540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  size_t nregs = ebl_frame_nregs (ebl);
5550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (nregs > 0);
5563e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard
5573e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard  /* The return register is special for setting the unwound->pc_state.  */
5583e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard  unsigned ra = frame->fde->cie->return_address_register;
5593e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard  bool ra_set = false;
5603e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard  ebl_dwarf_to_regno (ebl, &ra);
5613e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard
5620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  for (unsigned regno = 0; regno < nregs; regno++)
5630b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
5640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      Dwarf_Op reg_ops_mem[3], *reg_ops;
5650b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      size_t reg_nops;
5660b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (dwarf_frame_register (frame, regno, reg_ops_mem, &reg_ops,
5670b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil				&reg_nops) != 0)
5680b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
5690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_LIBDW);
5700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  continue;
5710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
5720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      Dwarf_Addr regval;
5730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (reg_nops == 0)
5740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
5750b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (reg_ops == reg_ops_mem)
5760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
5770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      /* REGNO is undefined.  */
5783e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	      if (regno == ra)
5790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
5800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      continue;
5810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
5820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  else if (reg_ops == NULL)
5830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
5840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      /* REGNO is same-value.  */
5850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      if (! state_get_reg (state, regno, &regval))
5860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		continue;
5870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
5880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  else
5890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
5900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
5910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      continue;
5920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
5930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
5940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      else if (! expr_eval (state, frame, reg_ops, reg_nops, &regval, bias))
5950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
5960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  /* PPC32 vDSO has various invalid operations, ignore them.  The
5970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	     register will look as unset causing an error later, if used.
5980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	     But PPC32 does not use such registers.  */
5990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  continue;
6000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
6013e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard
602c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard      /* Some architectures encode some extra info in the return address.  */
603c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard      if (regno == frame->fde->cie->return_address_register)
604c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard	regval &= ebl_func_addr_mask (ebl);
605c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard
6063e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard      /* This is another strange PPC[64] case.  There are two
6073e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	 registers numbers that can represent the same DWARF return
6083e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	 register number.  We only want one to actually set the return
60927aae18ce872409b70afef8503941c7e75c8d93dMark Wielaard	 register value.  But we always want to override the value if
61027aae18ce872409b70afef8503941c7e75c8d93dMark Wielaard	 the register is the actual CIE return address register.  */
61127aae18ce872409b70afef8503941c7e75c8d93dMark Wielaard      if (ra_set && regno != frame->fde->cie->return_address_register)
6123e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	{
6133e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	  unsigned r = regno;
6143e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	  if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
6153e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	    continue;
6163e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	}
6173e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard
6180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (! __libdwfl_frame_reg_set (unwound, regno, regval))
6190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
6200b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
6210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  continue;
6220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
6233e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard      else if (! ra_set)
6243e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	{
6253e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	  unsigned r = regno;
6263e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard          if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
6273e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	    ra_set = true;
6283e98ab73f31ed35fcd83e0e1a01147a559d1858bMark Wielaard	}
6290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
6300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (unwound->pc_state == DWFL_FRAME_STATE_ERROR
6310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      && __libdwfl_frame_reg_get (unwound,
6320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil				  frame->fde->cie->return_address_register,
6330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil				  &unwound->pc))
6340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
6350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      /* PPC32 __libc_start_main properly CFI-unwinds PC as zero.  Currently
6360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 none of the archs supported for unwinding have zero as a valid PC.  */
6370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (unwound->pc == 0)
6380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
6390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      else
64073be3d2d1a5dbdb6aa954b244524d21346af27d8Jose E. Marchesi        {
64173be3d2d1a5dbdb6aa954b244524d21346af27d8Jose E. Marchesi          unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
64273be3d2d1a5dbdb6aa954b244524d21346af27d8Jose E. Marchesi          /* In SPARC the return address register actually contains
64373be3d2d1a5dbdb6aa954b244524d21346af27d8Jose E. Marchesi             the address of the call instruction instead of the return
64473be3d2d1a5dbdb6aa954b244524d21346af27d8Jose E. Marchesi             address.  Therefore we add here an offset defined by the
64573be3d2d1a5dbdb6aa954b244524d21346af27d8Jose E. Marchesi             backend.  Most likely 0.  */
64673be3d2d1a5dbdb6aa954b244524d21346af27d8Jose E. Marchesi          unwound->pc += ebl_ra_offset (ebl);
64773be3d2d1a5dbdb6aa954b244524d21346af27d8Jose E. Marchesi        }
6480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
649e6e6cc83ea27413facb310ce48bebb1579a47130Mark Wielaard  free (frame);
6500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
6510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
652c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvilstatic bool
653c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvilsetfunc (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg)
654c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil{
655c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Frame *state = arg;
656c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Frame *unwound = state->unwound;
657c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  if (firstreg < 0)
658c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil    {
659c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      assert (firstreg == -1);
660c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      assert (nregs == 1);
661c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      assert (unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
662c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      unwound->pc = *regs;
663c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
664c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      return true;
665c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil    }
666c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  while (nregs--)
667c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil    if (! __libdwfl_frame_reg_set (unwound, firstreg++, *regs++))
668c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      return false;
669c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  return true;
670c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil}
671c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil
672c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvilstatic bool
673c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvilgetfunc (int firstreg, unsigned nregs, Dwarf_Word *regs, void *arg)
674c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil{
675c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Frame *state = arg;
676c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  assert (firstreg >= 0);
677c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  while (nregs--)
678c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil    if (! __libdwfl_frame_reg_get (state, firstreg++, regs++))
679c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      return false;
680c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  return true;
681c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil}
682c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil
683c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvilstatic bool
684c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvilreadfunc (Dwarf_Addr addr, Dwarf_Word *datap, void *arg)
685c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil{
686c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Frame *state = arg;
687c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Thread *thread = state->thread;
688c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Process *process = thread->process;
689c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  return process->callbacks->memory_read (process->dwfl, addr, datap,
690c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil					  process->callbacks_arg);
691c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil}
692c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil
6930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilvoid
6940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilinternal_function
6950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil__libdwfl_frame_unwind (Dwfl_Frame *state)
6960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
6970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (state->unwound)
6980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return;
6990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  /* Do not ask dwfl_frame_pc for ISACTIVATION, it would try to unwind STATE
7000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil     which would deadlock us.  */
7010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwarf_Addr pc;
7020b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  bool ok = INTUSE(dwfl_frame_pc) (state, &pc, NULL);
7030b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (ok);
7040b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  /* Check whether this is the initial frame or a signal frame.
7050b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil     Then we need to unwind from the original, unadjusted PC.  */
7060b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (! state->initial_frame && ! state->signal_frame)
7070b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    pc--;
7080b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (state->thread->process->dwfl, pc);
7090b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (mod == NULL)
7100b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    __libdwfl_seterrno (DWFL_E_NO_DWARF);
7110b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  else
7120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
7130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      Dwarf_Addr bias;
7140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias);
7150b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (cfi_eh)
7160b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
7170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  handle_cfi (state, pc - bias, cfi_eh, bias);
7180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (state->unwound)
7190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    return;
7200b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
7210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias);
7220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (cfi_dwarf)
7230b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
7240b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  handle_cfi (state, pc - bias, cfi_dwarf, bias);
7250b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (state->unwound)
7260b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    return;
7270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
7280b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
729c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  assert (state->unwound == NULL);
730c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Thread *thread = state->thread;
731c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Dwfl_Process *process = thread->process;
732c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  Ebl *ebl = process->ebl;
733c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  new_unwound (state);
734c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  state->unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
735c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  // &Dwfl_Frame.signal_frame cannot be passed as it is a bitfield.
736c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  bool signal_frame = false;
737c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  if (! ebl_unwind (ebl, pc, setfunc, getfunc, readfunc, state, &signal_frame))
738c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil    {
739c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      // Discard the unwind attempt.  During next __libdwfl_frame_unwind call
740c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      // we may have for example the appropriate Dwfl_Module already mapped.
741c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      assert (state->unwound->unwound == NULL);
742c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      free (state->unwound);
743c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      state->unwound = NULL;
744c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      // __libdwfl_seterrno has been called above.
745c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil      return;
746c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil    }
747c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  assert (state->unwound->pc_state == DWFL_FRAME_STATE_PC_SET);
748c6a41483f2986d5542c554981348f75b815ef9b1Jan Kratochvil  state->unwound->signal_frame = signal_frame;
7490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
750