13c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath/* DW_EH_PE_* support for libdw unwinder.
2b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard   Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc.
3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is part of elfutils.
43c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is free software; you can redistribute it and/or modify
6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   it under the terms of either
73c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU Lesser General Public License as published by the Free
9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 3 of the License, or (at
10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or
13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU General Public License as published by the Free
15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 2 of the License, or (at
16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or both in parallel, as here.
19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   elfutils is distributed in the hope that it will be useful, but
213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath   WITHOUT ANY WARRANTY; without even the implied warranty of
223c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
233c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath   General Public License for more details.
243c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
25de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   You should have received copies of the GNU General Public License and
26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   the GNU Lesser General Public License along with this program.  If
27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   not, see <http://www.gnu.org/licenses/>.  */
283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#ifndef _ENCODED_VALUE_H
303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#define _ENCODED_VALUE_H 1
313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include <dwarf.h>
333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include <stdlib.h>
343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include "libdwP.h"
35b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard#include "../libelf/common.h"
363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
38b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard/* Returns zero if the value is omitted, the encoding is unknown or
39b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard   the (leb128) size cannot be determined.  */
403c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic size_t __attribute__ ((unused))
413c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathencoded_value_size (const Elf_Data *data, const unsigned char e_ident[],
423c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		    uint8_t encoding, const uint8_t *p)
433c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{
443c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (encoding == DW_EH_PE_omit)
453c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    return 0;
463c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
473c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  switch (encoding & 0x07)
483c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
493c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_udata2:
503c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      return 2;
513c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_udata4:
523c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      return 4;
533c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_udata8:
543c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      return 8;
553c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
563c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_absptr:
573c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      return e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
583c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
593c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_uleb128:
603c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (p != NULL)
613c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
623c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  const uint8_t *end = p;
633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  while (end < (uint8_t *) data->d_buf + data->d_size)
643c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	    if (*end++ & 0x80u)
653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	      return end - p;
663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    default:
693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      return 0;
703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath}
723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
73b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard/* Returns zero when value was read successfully, minus one otherwise.  */
743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic inline int __attribute__ ((unused))
753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath__libdw_cfi_read_address_inc (const Dwarf_CFI *cache,
763c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			      const unsigned char **addrp,
773c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			      int width, Dwarf_Addr *ret)
783c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{
793c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  width = width ?: cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
803c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
813c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (cache->dbg != NULL)
823c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    return __libdw_read_address_inc (cache->dbg, IDX_debug_frame,
833c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath				     addrp, width, ret);
843c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
853c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  /* Only .debug_frame might have relocation to consider.
863c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath     Read plain values from .eh_frame data.  */
873c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
88b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard  const unsigned char *endp = cache->data->d.d_buf + cache->data->d.d_size;
89b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard  Dwarf eh_dbg = { .other_byte_order = MY_ELFDATA != cache->e_ident[EI_DATA] };
90b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard
913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (width == 4)
92b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard    {
93b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (*addrp + 4 > endp))
94b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	{
95b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	invalid_data:
96b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	  __libdw_seterrno (DWARF_E_INVALID_CFI);
97b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	  return -1;
98b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	}
99b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      *ret = read_4ubyte_unaligned_inc (&eh_dbg, *addrp);
100b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard    }
1013c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
102b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard    {
103b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (*addrp + 8 > endp))
104b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	goto invalid_data;
105b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      *ret = read_8ubyte_unaligned_inc (&eh_dbg, *addrp);
106b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard    }
1073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  return 0;
1083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath}
1093c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
110b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard/* Returns true on error, false otherwise. */
1113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic bool __attribute__ ((unused))
112b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaardread_encoded_value (const Dwarf_CFI *cache, uint8_t encoding,
113b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard		    const uint8_t **p, Dwarf_Addr *result)
1143c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{
1153c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  *result = 0;
1163c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  switch (encoding & 0x70)
1173c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
1183c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_absptr:
1193c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1203c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_pcrel:
1213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      *result = (cache->frame_vaddr
1223c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		 + (*p - (const uint8_t *) cache->data->d.d_buf));
1233c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1243c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_textrel:
1253c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      // ia64: segrel
1263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      *result = cache->textrel;
1273c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_datarel:
1293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      // i386: GOTOFF
1303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      // ia64: gprel
1313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      *result = cache->datarel;
1323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_funcrel:	/* XXX */
1343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_aligned:
1363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      {
137b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	const size_t size = encoded_value_size (&cache->data->d,
138b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard						cache->e_ident,
1397934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath						encoding, *p);
140b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	if (unlikely (size == 0))
141b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	  return true;
1423c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	size_t align = ((cache->frame_vaddr
1433c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			 + (*p - (const uint8_t *) cache->data->d.d_buf))
1447934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath			& (size - 1));
1453c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	if (align != 0)
1467934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath	  *p += size - align;
1473c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	break;
1483c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      }
1493c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1503c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    default:
151b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      __libdw_seterrno (DWARF_E_INVALID_CFI);
152b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      return true;
1533c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
1543c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
155031db7ce5f149c8469ac33f688a09ffb15c5d85dJosh Stone  Dwarf_Addr value = 0;
156b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard  const unsigned char *endp = cache->data->d.d_buf + cache->data->d.d_size;
1573c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  switch (encoding & 0x0f)
1583c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
1593c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_udata2:
160b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (*p + 2 > endp))
161b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	{
162b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	invalid_data:
163b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	  __libdw_seterrno (DWARF_E_INVALID_CFI);
164b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	  return true;
165b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	}
1663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      value = read_2ubyte_unaligned_inc (cache, *p);
1673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_sdata2:
170b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (*p + 2 > endp))
171b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	goto invalid_data;
1723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      value = read_2sbyte_unaligned_inc (cache, *p);
1733c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_udata4:
176b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (__libdw_cfi_read_address_inc (cache, p, 4, &value) != 0))
1777934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath	return true;
1783c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1793c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1803c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_sdata4:
181b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (__libdw_cfi_read_address_inc (cache, p, 4, &value) != 0))
1827934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath	return true;
1833c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      value = (Dwarf_Sword) (Elf32_Sword) value; /* Sign-extend.  */
1843c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1853c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1863c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_udata8:
1873c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_sdata8:
188b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (__libdw_cfi_read_address_inc (cache, p, 8, &value) != 0))
1897934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath	return true;
1903c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1923c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_absptr:
193b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (__libdw_cfi_read_address_inc (cache, p, 0, &value) != 0))
1947934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath	return true;
1953c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
1963c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1973c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_uleb128:
198b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      get_uleb128 (value, *p, endp);
1993c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
2003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
2013c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    case DW_EH_PE_sleb128:
202b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      get_sleb128 (value, *p, endp);
2033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      break;
2043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
2053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    default:
206b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      __libdw_seterrno (DWARF_E_INVALID_CFI);
207b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      return true;
2083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
2093c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
2103c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  *result += value;
2117934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath
2127934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath  if (encoding & DW_EH_PE_indirect)
2137934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath    {
2147934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath      if (unlikely (*result < cache->frame_vaddr))
2157934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath	return true;
2167934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath      *result -= cache->frame_vaddr;
2171ae83ee85404b345150104148b50c60ebcb79398Mark Wielaard      size_t ptrsize = encoded_value_size (NULL, cache->e_ident,
2181ae83ee85404b345150104148b50c60ebcb79398Mark Wielaard					   DW_EH_PE_absptr, NULL);
2191ae83ee85404b345150104148b50c60ebcb79398Mark Wielaard      if (unlikely (cache->data->d.d_size < ptrsize
2201ae83ee85404b345150104148b50c60ebcb79398Mark Wielaard		    || *result > (cache->data->d.d_size - ptrsize)))
2217934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath	return true;
2227934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath      const uint8_t *ptr = cache->data->d.d_buf + *result;
223b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard      if (unlikely (__libdw_cfi_read_address_inc (cache, &ptr, 0, result)
224b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard		    != 0))
225b4b2de9f1f1fb694b77371a61f808a1641bbafeaMark Wielaard	return true;
2267934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath    }
2277934ded435882538f8c551a3c2a9ed42d6d3c45aRoland McGrath
2283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  return false;
2293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath}
2303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
2313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#endif	/* encoded-value.h */
232