encoded-value.h revision 3c84db3b4b610bf636c4363abb6d3dac5ae020f9
13c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath/* DW_EH_PE_* support for libdw unwinder. 23c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Copyright (C) 2009 Red Hat, Inc. 33c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath This file is part of Red Hat elfutils. 43c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 53c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Red Hat elfutils is free software; you can redistribute it and/or modify 63c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath it under the terms of the GNU General Public License as published by the 73c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Free Software Foundation; version 2 of the License. 83c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 93c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Red Hat elfutils is distributed in the hope that it will be useful, but 103c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath WITHOUT ANY WARRANTY; without even the implied warranty of 113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 123c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath General Public License for more details. 133c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 143c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath You should have received a copy of the GNU General Public License along 153c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath with Red Hat elfutils; if not, write to the Free Software Foundation, 163c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 173c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 183c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath In addition, as a special exception, Red Hat, Inc. gives You the 193c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath additional right to link the code of Red Hat elfutils with code licensed 203c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath under any Open Source Initiative certified open source license 213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath (http://www.opensource.org/licenses/index.php) which requires the 223c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath distribution of source code with any binary distribution and to 233c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath distribute linked combinations of the two. Non-GPL Code permitted under 243c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath this exception must only link to the code of Red Hat elfutils through 253c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath those well defined interfaces identified in the file named EXCEPTION 263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath found in the source code files (the "Approved Interfaces"). The files 273c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath of Non-GPL Code may instantiate templates or use macros or inline 283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath functions from the Approved Interfaces without causing the resulting 293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath work to be covered by the GNU General Public License. Only Red Hat, 303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Inc. may make changes or additions to the list of Approved Interfaces. 313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Red Hat's grant of this exception is conditioned upon your not adding 323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath any new exceptions. If you wish to add a new Approved Interface or 333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath exception, please contact Red Hat. You must obey the GNU General Public 343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath License in all respects for all of the Red Hat elfutils code and other 353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath code used in conjunction with Red Hat elfutils except the Non-GPL Code 363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath covered by this exception. If you modify this file, you may extend this 373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath exception to your version of the file, but you are not obligated to do 383c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath so. If you do not wish to provide this exception without modification, 393c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath you must delete this exception statement from your version and license 403c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath this file solely under the GPL without exception. 413c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 423c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Red Hat elfutils is an included package of the Open Invention Network. 433c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath An included package of the Open Invention Network is a package for which 443c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Open Invention Network licensees cross-license their patents. No patent 453c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath license is granted, either expressly or impliedly, by designation as an 463c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath included package. Should you wish to participate in the Open Invention 473c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Network licensing program, please visit www.openinventionnetwork.com 483c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath <http://www.openinventionnetwork.com>. */ 493c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 503c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#ifndef _ENCODED_VALUE_H 513c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#define _ENCODED_VALUE_H 1 523c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 533c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include <dwarf.h> 543c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include <stdlib.h> 553c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#include "libdwP.h" 563c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 573c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 583c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic size_t __attribute__ ((unused)) 593c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathencoded_value_size (const Elf_Data *data, const unsigned char e_ident[], 603c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath uint8_t encoding, const uint8_t *p) 613c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{ 623c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (encoding == DW_EH_PE_omit) 633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return 0; 643c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath switch (encoding & 0x07) 663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_udata2: 683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return 2; 693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_udata4: 703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return 4; 713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_udata8: 723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return 8; 733c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_absptr: 753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 763c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 773c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_uleb128: 783c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (p != NULL) 793c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 803c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath const uint8_t *end = p; 813c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath while (end < (uint8_t *) data->d_buf + data->d_size) 823c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (*end++ & 0x80u) 833c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return end - p; 843c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 853c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 863c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath default: 873c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath abort (); 883c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return 0; 893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 903c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath} 913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 923c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic inline int __attribute__ ((unused)) 933c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath__libdw_cfi_read_address_inc (const Dwarf_CFI *cache, 943c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath const unsigned char **addrp, 953c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath int width, Dwarf_Addr *ret) 963c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{ 973c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath width = width ?: cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 983c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 993c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (cache->dbg != NULL) 1003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return __libdw_read_address_inc (cache->dbg, IDX_debug_frame, 1013c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath addrp, width, ret); 1023c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath /* Only .debug_frame might have relocation to consider. 1043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Read plain values from .eh_frame data. */ 1053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1063c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (width == 4) 1073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath *ret = read_4ubyte_unaligned_inc (cache, *addrp); 1083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath else 1093c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath *ret = read_8ubyte_unaligned_inc (cache, *addrp); 1103c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return 0; 1113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath} 1123c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1133c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic bool __attribute__ ((unused)) 1143c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathread_encoded_value (const Dwarf_CFI *cache, uint8_t encoding, const uint8_t **p, 1153c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Addr *result) 1163c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{ 1173c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath *result = 0; 1183c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath switch (encoding & 0x70) 1193c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 1203c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_absptr: 1213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1223c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_pcrel: 1233c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath *result = (cache->frame_vaddr 1243c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath + (*p - (const uint8_t *) cache->data->d.d_buf)); 1253c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_textrel: 1273c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath // ia64: segrel 1283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath *result = cache->textrel; 1293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_datarel: 1313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath // i386: GOTOFF 1323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath // ia64: gprel 1333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath *result = cache->datarel; 1343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_funcrel: /* XXX */ 1363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_aligned: 1383c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 1393c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath const size_t address_size 1403c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath = cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 1413c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath size_t align = ((cache->frame_vaddr 1423c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath + (*p - (const uint8_t *) cache->data->d.d_buf)) 1433c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath & (address_size - 1)); 1443c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (align != 0) 1453c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath *p += address_size - align; 1463c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1473c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 1483c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1493c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath default: 1503c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath abort (); 1513c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 1523c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1533c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Addr value; 1543c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath switch (encoding & 0x0f) 1553c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 1563c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_udata2: 1573c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath value = read_2ubyte_unaligned_inc (cache, *p); 1583c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1593c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1603c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_sdata2: 1613c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath value = read_2sbyte_unaligned_inc (cache, *p); 1623c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1643c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_udata4: 1653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (__libdw_cfi_read_address_inc (cache, p, 4, &value)) 1663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return false; 1673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_sdata4: 1703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (__libdw_cfi_read_address_inc (cache, p, 4, &value)) 1713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return false; 1723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath value = (Dwarf_Sword) (Elf32_Sword) value; /* Sign-extend. */ 1733c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_udata8: 1763c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_sdata8: 1773c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (__libdw_cfi_read_address_inc (cache, p, 8, &value)) 1783c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return false; 1793c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1803c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1813c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_absptr: 1823c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (__libdw_cfi_read_address_inc (cache, p, 0, &value)) 1833c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return false; 1843c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1853c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1863c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_uleb128: 1873c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath get_uleb128 (value, *p); 1883c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1903c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath case DW_EH_PE_sleb128: 1913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath get_sleb128 (value, *p); 1923c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath break; 1933c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1943c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath default: 1953c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath abort (); 1963c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 1973c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 1983c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath *result += value; 1993c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return false; 2003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath} 2013c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 2023c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath#endif /* encoded-value.h */ 203