13c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath/* Advance to next CFI entry.
27a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard   Copyright (C) 2009-2010, 2014 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#ifdef HAVE_CONFIG_H
303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath# include <config.h>
313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#endif
323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include "cfi.h"
343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include "encoded-value.h"
353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include <string.h>
373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
383c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
393c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathint
40aa1c2ca808a267a5a3c372de5461c1f67f9a8869Chih-Hung Hsiehdwarf_next_cfi (const unsigned char e_ident[],
41aa1c2ca808a267a5a3c372de5461c1f67f9a8869Chih-Hung Hsieh		Elf_Data *data,
42aa1c2ca808a267a5a3c372de5461c1f67f9a8869Chih-Hung Hsieh		bool eh_frame_p,
43aa1c2ca808a267a5a3c372de5461c1f67f9a8869Chih-Hung Hsieh		Dwarf_Off off,
44aa1c2ca808a267a5a3c372de5461c1f67f9a8869Chih-Hung Hsieh		Dwarf_Off *next_off,
45aa1c2ca808a267a5a3c372de5461c1f67f9a8869Chih-Hung Hsieh		Dwarf_CFI_Entry *entry)
463c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{
473c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  /* Dummy struct for memory-access.h macros.  */
483c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  BYTE_ORDER_DUMMY (dw, e_ident);
493c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
503c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  /* If we reached the end before don't do anything.  */
513c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (off == (Dwarf_Off) -1l
523c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      /* Make sure there is enough space in the .debug_frame section
533c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	 for at least the initial word.  We cannot test the rest since
543c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	 we don't know yet whether this is a 64-bit object or not.  */
553c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      || unlikely (off + 4 >= data->d_size))
563c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
573c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      *next_off = (Dwarf_Off) -1l;
583c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      return 1;
593c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
603c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
613c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  /* This points into the .debug_frame section at the start of the entry.  */
623c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  const uint8_t *bytes = data->d_buf + off;
633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  const uint8_t *limit = data->d_buf + data->d_size;
643c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  /* The format of a CFI entry is described in DWARF3 6.4.1:
663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath   */
673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  uint64_t length = read_4ubyte_unaligned_inc (&dw, bytes);
693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  size_t offset_size = 4;
703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (length == DWARF3_LENGTH_64_BIT)
713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      /* This is the 64-bit DWARF format.  */
733c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      offset_size = 8;
743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (unlikely (limit - bytes < 8))
753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
763c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	invalid:
773c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
783c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  return -1;
793c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
803c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      length = read_8ubyte_unaligned_inc (&dw, bytes);
813c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
823c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (unlikely ((uint64_t) (limit - bytes) < length)
833c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      || unlikely (length < offset_size + 1))
843c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    goto invalid;
853c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
863c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  /* Now we know how large the entry is.  Note the trick in the
873c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath     computation.  If the offset_size is 4 the '- 4' term undoes the
883c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath     '2 *'.  If offset_size is 8 this term computes the size of the
893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath     escape value plus the 8 byte offset.  */
903c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  *next_off = off + (2 * offset_size - 4) + length;
913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
923c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  limit = bytes + length;
933c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
943c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  const uint8_t *const cie_pointer_start = bytes;
953c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (offset_size == 8)
963c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    entry->cie.CIE_id = read_8ubyte_unaligned_inc (&dw, bytes);
973c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
983c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
993c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      entry->cie.CIE_id = read_4ubyte_unaligned_inc (&dw, bytes);
1003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      /* Canonicalize the 32-bit CIE_ID value to 64 bits.  */
1013c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (!eh_frame_p && entry->cie.CIE_id == DW_CIE_ID_32)
1023c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	entry->cie.CIE_id = DW_CIE_ID_64;
1033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
1043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (eh_frame_p)
1053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
1063c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      /* Canonicalize the .eh_frame CIE pointer to .debug_frame format.  */
1073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (entry->cie.CIE_id == 0)
1083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	entry->cie.CIE_id = DW_CIE_ID_64;
1093c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      else
1103c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
1113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  /* In .eh_frame format, a CIE pointer is the distance from where
1123c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	     it appears back to the beginning of the CIE.  */
1133c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  ptrdiff_t pos = cie_pointer_start - (const uint8_t *) data->d_buf;
1143c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  if (unlikely (entry->cie.CIE_id > (Dwarf_Off) pos)
1153c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	      || unlikely (pos <= (ptrdiff_t) offset_size))
1163c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	    goto invalid;
1173c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  entry->cie.CIE_id = pos - entry->cie.CIE_id;
1183c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
1193c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
1203c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (entry->cie.CIE_id == DW_CIE_ID_64)
1223c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
1233c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      /* Read the version stamp.  Always an 8-bit value.  */
1243c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      uint8_t version = *bytes++;
1253c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1269bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath      if (version != 1 && (unlikely (version < 3) || unlikely (version > 4)))
1273c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	goto invalid;
1283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      entry->cie.augmentation = (const char *) bytes;
1303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      bytes = memchr (bytes, '\0', limit - bytes);
1329bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath      if (unlikely (bytes == NULL))
1333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	goto invalid;
1343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      ++bytes;
1353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1369bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath      /* The address size for CFI is implicit in the ELF class.  */
137c70ebc0587ad1c549a3fe7f16a563bf4d6782aa7Roland McGrath      uint_fast8_t address_size = e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
138c70ebc0587ad1c549a3fe7f16a563bf4d6782aa7Roland McGrath      uint_fast8_t segment_size = 0;
1399bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath      if (version >= 4)
1409bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	{
1419bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	  if (unlikely (limit - bytes < 5))
1429bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	    goto invalid;
1439bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	  /* XXX We don't actually support address_size not matching the class.
1449bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	     To do so, we'd have to return it here so that intern_new_cie
1459bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	     could use it choose a specific fde_encoding.  */
1469bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	  if (unlikely (*bytes != address_size))
1479bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	    {
1489bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	      __libdw_seterrno (DWARF_E_VERSION);
1499bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	      return -1;
1509bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	    }
1519bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	  address_size = *bytes++;
1529bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	  segment_size = *bytes++;
1539bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	  /* We don't actually support segment selectors.  We'd have to
1549bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	     roll this into the fde_encoding bits or something.  */
1559bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	  if (unlikely (segment_size != 0))
1569bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	    {
1579bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	      __libdw_seterrno (DWARF_E_VERSION);
1589bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	      return -1;
1599bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	    }
1609bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath	}
1619bcd2657ab6a761e9b218a3b3ba578756b6f7a23Roland McGrath
1623c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      const char *ap = entry->cie.augmentation;
1633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1643c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      /* g++ v2 "eh" has pointer immediately following augmentation string,
1653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	 so it must be handled first.  */
1663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (unlikely (ap[0] == 'e' && ap[1] == 'h'))
1673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
1683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  ap += 2;
1693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  bytes += address_size;
1703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
1713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1727a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard      if (bytes >= limit)
1737a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard	goto invalid;
1747a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard      get_uleb128 (entry->cie.code_alignment_factor, bytes, limit);
1757a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard
1767a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard      if (bytes >= limit)
1777a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard	goto invalid;
1787a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard      get_sleb128 (entry->cie.data_alignment_factor, bytes, limit);
1797a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard
1807a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard      if (bytes >= limit)
1817a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard	goto invalid;
1823c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1834a87dfa1cc8dc8b6515e89690ee266e5e0381e5eRoland McGrath      if (version >= 3)		/* DWARF 3+ */
1847a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard	get_uleb128 (entry->cie.return_address_register, bytes, limit);
1853c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      else			/* DWARF 2 */
1863c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	entry->cie.return_address_register = *bytes++;
1873c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
1883c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      /* If we have sized augmentation data,
1893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	 we don't need to grok it all.  */
1903c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      entry->cie.fde_augmentation_data_size = 0;
1913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      bool sized_augmentation = *ap == 'z';
1923c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (sized_augmentation)
1933c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
1947a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard	  if (bytes >= limit)
1957a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard	    goto invalid;
1967a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard	  get_uleb128 (entry->cie.augmentation_data_size, bytes, limit);
1973c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  if ((Dwarf_Word) (limit - bytes) < entry->cie.augmentation_data_size)
1983c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	    goto invalid;
1993c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  entry->cie.augmentation_data = bytes;
2003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  bytes += entry->cie.augmentation_data_size;
2013c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
2023c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      else
2033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
2043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  entry->cie.augmentation_data = bytes;
2053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
2063c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  for (; *ap != '\0'; ++ap)
2073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	    {
2083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	      uint8_t encoding;
2093c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	      switch (*ap)
2103c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		{
2113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		case 'L':		/* Skip LSDA pointer encoding byte.  */
2123c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		case 'R':		/* Skip FDE address encoding byte.  */
2133c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  encoding = *bytes++;
2143c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  entry->cie.fde_augmentation_data_size
2153c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		    += encoded_value_size (data, e_ident, encoding, NULL);
2163c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  continue;
2173c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		case 'P':   /* Skip encoded personality routine pointer. */
2183c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  encoding = *bytes++;
2193c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  bytes += encoded_value_size (data, e_ident, encoding, bytes);
2203c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  continue;
2213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		case 'S':		/* Skip signal-frame flag.  */
2223c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  continue;
2233c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		default:
2243c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  /* Unknown augmentation string.  initial_instructions might
2253c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		     actually start with some augmentation data.  */
2263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		  break;
2273c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath		}
2283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	      break;
2293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	    }
2303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  entry->cie.augmentation_data_size
2313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	    = bytes - entry->cie.augmentation_data;
2323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
2333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
2343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      entry->cie.initial_instructions = bytes;
2353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      entry->cie.initial_instructions_end = limit;
2363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
2373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
2383c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
2393c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      entry->fde.start = bytes;
2403c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      entry->fde.end = limit;
2413c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
2423c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
2433c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  return 0;
2443c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath}
2453c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathINTDEF (dwarf_next_cfi)
246