1 /* Advance to next CFI entry.
2 Copyright (C) 2009-2010 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
18 or both in parallel, as here.
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
34 #include "encoded-value.h"
40 dwarf_next_cfi (e_ident, data, eh_frame_p, off, next_off, entry)
41 const unsigned char e_ident[];
46 Dwarf_CFI_Entry *entry;
48 /* Dummy struct for memory-access.h macros. */
49 BYTE_ORDER_DUMMY (dw, e_ident);
51 /* If we reached the end before don't do anything. */
52 if (off == (Dwarf_Off) -1l
53 /* Make sure there is enough space in the .debug_frame section
54 for at least the initial word. We cannot test the rest since
55 we don't know yet whether this is a 64-bit object or not. */
56 || unlikely (off + 4 >= data->d_size))
58 *next_off = (Dwarf_Off) -1l;
62 /* This points into the .debug_frame section at the start of the entry. */
63 const uint8_t *bytes = data->d_buf + off;
64 const uint8_t *limit = data->d_buf + data->d_size;
66 /* The format of a CFI entry is described in DWARF3 6.4.1:
69 uint64_t length = read_4ubyte_unaligned_inc (&dw, bytes);
70 size_t offset_size = 4;
71 if (length == DWARF3_LENGTH_64_BIT)
73 /* This is the 64-bit DWARF format. */
75 if (unlikely (limit - bytes < 8))
78 __libdw_seterrno (DWARF_E_INVALID_DWARF);
81 length = read_8ubyte_unaligned_inc (&dw, bytes);
83 if (unlikely ((uint64_t) (limit - bytes) < length)
84 || unlikely (length < offset_size + 1))
87 /* Now we know how large the entry is. Note the trick in the
88 computation. If the offset_size is 4 the '- 4' term undoes the
89 '2 *'. If offset_size is 8 this term computes the size of the
90 escape value plus the 8 byte offset. */
91 *next_off = off + (2 * offset_size - 4) + length;
93 limit = bytes + length;
95 const uint8_t *const cie_pointer_start = bytes;
97 entry->cie.CIE_id = read_8ubyte_unaligned_inc (&dw, bytes);
100 entry->cie.CIE_id = read_4ubyte_unaligned_inc (&dw, bytes);
101 /* Canonicalize the 32-bit CIE_ID value to 64 bits. */
102 if (!eh_frame_p && entry->cie.CIE_id == DW_CIE_ID_32)
103 entry->cie.CIE_id = DW_CIE_ID_64;
107 /* Canonicalize the .eh_frame CIE pointer to .debug_frame format. */
108 if (entry->cie.CIE_id == 0)
109 entry->cie.CIE_id = DW_CIE_ID_64;
112 /* In .eh_frame format, a CIE pointer is the distance from where
113 it appears back to the beginning of the CIE. */
114 ptrdiff_t pos = cie_pointer_start - (const uint8_t *) data->d_buf;
115 if (unlikely (entry->cie.CIE_id > (Dwarf_Off) pos)
116 || unlikely (pos <= (ptrdiff_t) offset_size))
118 entry->cie.CIE_id = pos - entry->cie.CIE_id;
122 if (entry->cie.CIE_id == DW_CIE_ID_64)
124 /* Read the version stamp. Always an 8-bit value. */
125 uint8_t version = *bytes++;
127 if (version != 1 && (unlikely (version < 3) || unlikely (version > 4)))
130 entry->cie.augmentation = (const char *) bytes;
132 bytes = memchr (bytes, '\0', limit - bytes);
133 if (unlikely (bytes == NULL))
137 /* The address size for CFI is implicit in the ELF class. */
138 uint_fast8_t address_size = e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
139 uint_fast8_t segment_size = 0;
142 if (unlikely (limit - bytes < 5))
144 /* XXX We don't actually support address_size not matching the class.
145 To do so, we'd have to return it here so that intern_new_cie
146 could use it choose a specific fde_encoding. */
147 if (unlikely (*bytes != address_size))
149 __libdw_seterrno (DWARF_E_VERSION);
152 address_size = *bytes++;
153 segment_size = *bytes++;
154 /* We don't actually support segment selectors. We'd have to
155 roll this into the fde_encoding bits or something. */
156 if (unlikely (segment_size != 0))
158 __libdw_seterrno (DWARF_E_VERSION);
163 const char *ap = entry->cie.augmentation;
165 /* g++ v2 "eh" has pointer immediately following augmentation string,
166 so it must be handled first. */
167 if (unlikely (ap[0] == 'e' && ap[1] == 'h'))
170 bytes += address_size;
173 get_uleb128 (entry->cie.code_alignment_factor, bytes);
174 get_sleb128 (entry->cie.data_alignment_factor, bytes);
176 if (version >= 3) /* DWARF 3+ */
177 get_uleb128 (entry->cie.return_address_register, bytes);
179 entry->cie.return_address_register = *bytes++;
181 /* If we have sized augmentation data,
182 we don't need to grok it all. */
183 entry->cie.fde_augmentation_data_size = 0;
184 bool sized_augmentation = *ap == 'z';
185 if (sized_augmentation)
187 get_uleb128 (entry->cie.augmentation_data_size, bytes);
188 if ((Dwarf_Word) (limit - bytes) < entry->cie.augmentation_data_size)
190 entry->cie.augmentation_data = bytes;
191 bytes += entry->cie.augmentation_data_size;
195 entry->cie.augmentation_data = bytes;
197 for (; *ap != '\0'; ++ap)
202 case 'L': /* Skip LSDA pointer encoding byte. */
203 case 'R': /* Skip FDE address encoding byte. */
205 entry->cie.fde_augmentation_data_size
206 += encoded_value_size (data, e_ident, encoding, NULL);
208 case 'P': /* Skip encoded personality routine pointer. */
210 bytes += encoded_value_size (data, e_ident, encoding, bytes);
212 case 'S': /* Skip signal-frame flag. */
215 /* Unknown augmentation string. initial_instructions might
216 actually start with some augmentation data. */
221 entry->cie.augmentation_data_size
222 = bytes - entry->cie.augmentation_data;
225 entry->cie.initial_instructions = bytes;
226 entry->cie.initial_instructions_end = limit;
230 entry->fde.start = bytes;
231 entry->fde.end = limit;
236 INTDEF (dwarf_next_cfi)