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, ®no)) 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, ®no)) 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, ®_ops, 5670b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil ®_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, ®val)) 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, ®val, 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