diff options
Diffstat (limited to 'src/libdw/dwarf_next_cfi.c')
-rw-r--r-- | src/libdw/dwarf_next_cfi.c | 246 |
1 files changed, 0 insertions, 246 deletions
diff --git a/src/libdw/dwarf_next_cfi.c b/src/libdw/dwarf_next_cfi.c deleted file mode 100644 index b5af49e3..00000000 --- a/src/libdw/dwarf_next_cfi.c +++ /dev/null @@ -1,246 +0,0 @@ -/* Advance to next CFI entry. - Copyright (C) 2009-2010, 2014 Red Hat, Inc. - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "cfi.h" -#include "encoded-value.h" - -#include <string.h> - - -int -dwarf_next_cfi (e_ident, data, eh_frame_p, off, next_off, entry) - const unsigned char e_ident[]; - Elf_Data *data; - bool eh_frame_p; - Dwarf_Off off; - Dwarf_Off *next_off; - Dwarf_CFI_Entry *entry; -{ - /* Dummy struct for memory-access.h macros. */ - BYTE_ORDER_DUMMY (dw, e_ident); - - /* If we reached the end before don't do anything. */ - if (off == (Dwarf_Off) -1l - /* Make sure there is enough space in the .debug_frame section - for at least the initial word. We cannot test the rest since - we don't know yet whether this is a 64-bit object or not. */ - || unlikely (off + 4 >= data->d_size)) - { - *next_off = (Dwarf_Off) -1l; - return 1; - } - - /* This points into the .debug_frame section at the start of the entry. */ - const uint8_t *bytes = data->d_buf + off; - const uint8_t *limit = data->d_buf + data->d_size; - - /* The format of a CFI entry is described in DWARF3 6.4.1: - */ - - uint64_t length = read_4ubyte_unaligned_inc (&dw, bytes); - size_t offset_size = 4; - if (length == DWARF3_LENGTH_64_BIT) - { - /* This is the 64-bit DWARF format. */ - offset_size = 8; - if (unlikely (limit - bytes < 8)) - { - invalid: - __libdw_seterrno (DWARF_E_INVALID_DWARF); - return -1; - } - length = read_8ubyte_unaligned_inc (&dw, bytes); - } - if (unlikely ((uint64_t) (limit - bytes) < length) - || unlikely (length < offset_size + 1)) - goto invalid; - - /* Now we know how large the entry is. Note the trick in the - computation. If the offset_size is 4 the '- 4' term undoes the - '2 *'. If offset_size is 8 this term computes the size of the - escape value plus the 8 byte offset. */ - *next_off = off + (2 * offset_size - 4) + length; - - limit = bytes + length; - - const uint8_t *const cie_pointer_start = bytes; - if (offset_size == 8) - entry->cie.CIE_id = read_8ubyte_unaligned_inc (&dw, bytes); - else - { - entry->cie.CIE_id = read_4ubyte_unaligned_inc (&dw, bytes); - /* Canonicalize the 32-bit CIE_ID value to 64 bits. */ - if (!eh_frame_p && entry->cie.CIE_id == DW_CIE_ID_32) - entry->cie.CIE_id = DW_CIE_ID_64; - } - if (eh_frame_p) - { - /* Canonicalize the .eh_frame CIE pointer to .debug_frame format. */ - if (entry->cie.CIE_id == 0) - entry->cie.CIE_id = DW_CIE_ID_64; - else - { - /* In .eh_frame format, a CIE pointer is the distance from where - it appears back to the beginning of the CIE. */ - ptrdiff_t pos = cie_pointer_start - (const uint8_t *) data->d_buf; - if (unlikely (entry->cie.CIE_id > (Dwarf_Off) pos) - || unlikely (pos <= (ptrdiff_t) offset_size)) - goto invalid; - entry->cie.CIE_id = pos - entry->cie.CIE_id; - } - } - - if (entry->cie.CIE_id == DW_CIE_ID_64) - { - /* Read the version stamp. Always an 8-bit value. */ - uint8_t version = *bytes++; - - if (version != 1 && (unlikely (version < 3) || unlikely (version > 4))) - goto invalid; - - entry->cie.augmentation = (const char *) bytes; - - bytes = memchr (bytes, '\0', limit - bytes); - if (unlikely (bytes == NULL)) - goto invalid; - ++bytes; - - /* The address size for CFI is implicit in the ELF class. */ - uint_fast8_t address_size = e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; - uint_fast8_t segment_size = 0; - if (version >= 4) - { - if (unlikely (limit - bytes < 5)) - goto invalid; - /* XXX We don't actually support address_size not matching the class. - To do so, we'd have to return it here so that intern_new_cie - could use it choose a specific fde_encoding. */ - if (unlikely (*bytes != address_size)) - { - __libdw_seterrno (DWARF_E_VERSION); - return -1; - } - address_size = *bytes++; - segment_size = *bytes++; - /* We don't actually support segment selectors. We'd have to - roll this into the fde_encoding bits or something. */ - if (unlikely (segment_size != 0)) - { - __libdw_seterrno (DWARF_E_VERSION); - return -1; - } - } - - const char *ap = entry->cie.augmentation; - - /* g++ v2 "eh" has pointer immediately following augmentation string, - so it must be handled first. */ - if (unlikely (ap[0] == 'e' && ap[1] == 'h')) - { - ap += 2; - bytes += address_size; - } - - if (bytes >= limit) - goto invalid; - get_uleb128 (entry->cie.code_alignment_factor, bytes, limit); - - if (bytes >= limit) - goto invalid; - get_sleb128 (entry->cie.data_alignment_factor, bytes, limit); - - if (bytes >= limit) - goto invalid; - - if (version >= 3) /* DWARF 3+ */ - get_uleb128 (entry->cie.return_address_register, bytes, limit); - else /* DWARF 2 */ - entry->cie.return_address_register = *bytes++; - - /* If we have sized augmentation data, - we don't need to grok it all. */ - entry->cie.fde_augmentation_data_size = 0; - bool sized_augmentation = *ap == 'z'; - if (sized_augmentation) - { - if (bytes >= limit) - goto invalid; - get_uleb128 (entry->cie.augmentation_data_size, bytes, limit); - if ((Dwarf_Word) (limit - bytes) < entry->cie.augmentation_data_size) - goto invalid; - entry->cie.augmentation_data = bytes; - bytes += entry->cie.augmentation_data_size; - } - else - { - entry->cie.augmentation_data = bytes; - - for (; *ap != '\0'; ++ap) - { - uint8_t encoding; - switch (*ap) - { - case 'L': /* Skip LSDA pointer encoding byte. */ - case 'R': /* Skip FDE address encoding byte. */ - encoding = *bytes++; - entry->cie.fde_augmentation_data_size - += encoded_value_size (data, e_ident, encoding, NULL); - continue; - case 'P': /* Skip encoded personality routine pointer. */ - encoding = *bytes++; - bytes += encoded_value_size (data, e_ident, encoding, bytes); - continue; - case 'S': /* Skip signal-frame flag. */ - continue; - default: - /* Unknown augmentation string. initial_instructions might - actually start with some augmentation data. */ - break; - } - break; - } - entry->cie.augmentation_data_size - = bytes - entry->cie.augmentation_data; - } - - entry->cie.initial_instructions = bytes; - entry->cie.initial_instructions_end = limit; - } - else - { - entry->fde.start = bytes; - entry->fde.end = limit; - } - - return 0; -} -INTDEF (dwarf_next_cfi) |