From: Roland McGrath Date: Sun, 29 Mar 2009 23:59:10 +0000 (-0700) Subject: Fully hide Ebl inside libdw for CFI interface. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=07e691569dd995df89d15bad78689fa1b1833258;p=thirdparty%2Felfutils.git Fully hide Ebl inside libdw for CFI interface. --- diff --git a/libdw/Makefile.am b/libdw/Makefile.am index 852e57c39..82e46dc5a 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -88,8 +88,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ cie.c fde.c unwind.c frame-cache.c \ dwarf_frame_info.c dwarf_frame_cfa.c dwarf_frame_register.c \ dwarf_cfi_addrframe.c \ - dwarf_getcfi.c dwarf_getcfi_elf.c \ - dwarf_cfi_setebl.c dwarf_cfi_end.c + dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c if MAINTAINER_MODE BUILT_SOURCES = $(srcdir)/known-dwarf.h diff --git a/libdw/dwarf_cfi_setebl.c b/libdw/dwarf_cfi_setebl.c deleted file mode 100644 index 10da0c23c..000000000 --- a/libdw/dwarf_cfi_setebl.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Associate Ebl handle with Dwarf_CFI handle. - Copyright (C) 2006 Red Hat, Inc. - This file is part of Red Hat elfutils. - - Red Hat elfutils is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by the - Free Software Foundation; version 2 of the License. - - Red Hat 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 a copy of the GNU General Public License along - with Red Hat elfutils; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. - - In addition, as a special exception, Red Hat, Inc. gives You the - additional right to link the code of Red Hat elfutils with code licensed - under any Open Source Initiative certified open source license - (http://www.opensource.org/licenses/index.php) which requires the - distribution of source code with any binary distribution and to - distribute linked combinations of the two. Non-GPL Code permitted under - this exception must only link to the code of Red Hat elfutils through - those well defined interfaces identified in the file named EXCEPTION - found in the source code files (the "Approved Interfaces"). The files - of Non-GPL Code may instantiate templates or use macros or inline - functions from the Approved Interfaces without causing the resulting - work to be covered by the GNU General Public License. Only Red Hat, - Inc. may make changes or additions to the list of Approved Interfaces. - Red Hat's grant of this exception is conditioned upon your not adding - any new exceptions. If you wish to add a new Approved Interface or - exception, please contact Red Hat. You must obey the GNU General Public - License in all respects for all of the Red Hat elfutils code and other - code used in conjunction with Red Hat elfutils except the Non-GPL Code - covered by this exception. If you modify this file, you may extend this - exception to your version of the file, but you are not obligated to do - so. If you do not wish to provide this exception without modification, - you must delete this exception statement from your version and license - this file solely under the GPL without exception. - - Red Hat elfutils is an included package of the Open Invention Network. - An included package of the Open Invention Network is a package for which - Open Invention Network licensees cross-license their patents. No patent - license is granted, either expressly or impliedly, by designation as an - included package. Should you wish to participate in the Open Invention - Network licensing program, please visit www.openinventionnetwork.com - . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "libdwP.h" -#include "unwindP.h" -#include "../libebl/libebl.h" - -int -dwarf_cfi_setebl (cfi, ebl) - Dwarf_CFI *cfi; - Ebl *ebl; -{ - if (cfi == NULL) - return -1; - - cfi->ebl = ebl; - - return 0; -} -INTDEF (dwarf_cfi_setebl) diff --git a/libdw/libdw.map b/libdw/libdw.map index 93ca3c97f..598c9de72 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -203,7 +203,6 @@ ELFUTILS_0.140_UNWIND { dwarf_getcfi_elf; dwarf_cfi_addrframe; dwarf_cfi_end; - dwarf_cfi_setebl; dwarf_frame_cfa; dwarf_frame_register; dwarf_frame_info; diff --git a/libdw/unwind.c b/libdw/unwind.c index 487292468..5d83cb4b2 100644 --- a/libdw/unwind.c +++ b/libdw/unwind.c @@ -392,78 +392,100 @@ execute_cfi (Dwarf_CFI *cache, return result; } -int -internal_function -__libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde, - Dwarf_Addr address, Dwarf_Frame **frame) +static int +cie_cache_initial_state (Dwarf_CFI *cache, struct dwarf_cie *cie) { - if (fde->cie->initial_state == NULL) - { - /* This CIE has not been used before. Play out its initial - instructions and cache the initial state that results. */ + int result = DWARF_E_NOERROR; - Dwarf_Frame *cie_fs = calloc (1, sizeof (Dwarf_Frame)); - if (unlikely (cie_fs == NULL)) - return DWARF_E_NOMEM; + if (likely (cie->initial_state != NULL)) + return result; + + /* This CIE has not been used before. Play out its initial + instructions and cache the initial state that results. + First we'll let the backend fill in the default initial + state for this machine's ABI. */ - int result = DWARF_E_NOERROR; + Dwarf_CIE abi_info = { CIE_ID, 1, 1, -1, "", NULL, 0, 0, NULL, NULL }; - /* First we'll let the backend fill in the default initial - state for this machine's ABI. */ + /* Make sure we have a backend handle cached. */ + if (unlikely (cache->ebl == NULL)) + { + cache->ebl = ebl_openbackend (cache->elf); + if (unlikely (cache->ebl == NULL)) + cache->ebl = (void *) -1l; + } - Dwarf_CIE abi_info = { CIE_ID, 1, 1, -1, "", NULL, 0, 0, NULL, NULL }; - if (cache->ebl != NULL && ebl_abi_cfi (cache->ebl, &abi_info) < 0) - return DWARF_E_UNKNOWN_ERROR; + /* Fetch the ABI's default CFI program. */ + if (likely (cache->ebl != (void *) -1l) + && unlikely (ebl_abi_cfi (cache->ebl, &abi_info) < 0)) + return DWARF_E_UNKNOWN_ERROR; - /* If the default state of any register is not "undefined" - (i.e. call-clobbered), then the backend supplies instructions - for the standard initial state. */ - if (abi_info.initial_instructions_end > abi_info.initial_instructions) + Dwarf_Frame *cie_fs = calloc (1, sizeof (Dwarf_Frame)); + if (unlikely (cie_fs == NULL)) + return DWARF_E_NOMEM; + + /* If the default state of any register is not "undefined" + (i.e. call-clobbered), then the backend supplies instructions + for the standard initial state. */ + if (abi_info.initial_instructions_end > abi_info.initial_instructions) + { + /* Dummy CIE for backend's instructions. */ + struct dwarf_cie abi_cie = { - /* Dummy CIE for backend's instructions. */ - struct dwarf_cie abi_cie = - { - .code_alignment_factor = abi_info.code_alignment_factor, - .data_alignment_factor = abi_info.data_alignment_factor, - }; - result = execute_cfi (cache, &abi_cie, &cie_fs, - abi_info.initial_instructions, - abi_info.initial_instructions_end, true, - 0, (Dwarf_Addr) -1l); - } + .code_alignment_factor = abi_info.code_alignment_factor, + .data_alignment_factor = abi_info.data_alignment_factor, + }; + result = execute_cfi (cache, &abi_cie, &cie_fs, + abi_info.initial_instructions, + abi_info.initial_instructions_end, true, + 0, (Dwarf_Addr) -1l); + } + + /* Now run the CIE's initial instructions. */ + if (cie->initial_instructions_end > cie->initial_instructions + && likely (result == DWARF_E_NOERROR)) + result = execute_cfi (cache, cie, &cie_fs, + cie->initial_instructions, + cie->initial_instructions_end, false, + 0, (Dwarf_Addr) -1l); - /* Now run the CIE's initial instructions. */ - if (fde->cie->initial_instructions_end > fde->cie->initial_instructions - && result == DWARF_E_NOERROR) - result = execute_cfi (cache, fde->cie, &cie_fs, - fde->cie->initial_instructions, - fde->cie->initial_instructions_end, false, - 0, (Dwarf_Addr) -1l); - - if (result != DWARF_E_NOERROR) - return result; - - /* Now we have the initial state of things that all - FDEs using this CIE will start from. */ - cie_fs->cache = cache; - fde->cie->initial_state = cie_fs; + if (unlikely (result != DWARF_E_NOERROR)) + { + free (cie_fs); + return result; } - Dwarf_Frame *fs = duplicate_frame_state (fde->cie->initial_state, NULL); - if (unlikely (fs == NULL)) - return DWARF_E_NOMEM; + /* Now we have the initial state of things that all + FDEs using this CIE will start from. */ + cie_fs->cache = cache; + cie->initial_state = cie_fs; + + return result; +} + +int +internal_function +__libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde, + Dwarf_Addr address, Dwarf_Frame **frame) +{ + int result = cie_cache_initial_state (cache, fde->cie); + if (likely (result == DWARF_E_NOERROR)) + { + Dwarf_Frame *fs = duplicate_frame_state (fde->cie->initial_state, NULL); + if (unlikely (fs == NULL)) + return DWARF_E_NOMEM; - fs->fde = fde; - fs->start = fde->start; - fs->end = fde->end; + fs->fde = fde; + fs->start = fde->start; + fs->end = fde->end; - int result = execute_cfi (cache, fde->cie, &fs, + result = execute_cfi (cache, fde->cie, &fs, fde->instructions, fde->instructions_end, false, fde->start, address); - if (unlikely (result != DWARF_E_NOERROR)) - free (fs); - else - *frame = fs; - + if (unlikely (result != DWARF_E_NOERROR)) + free (fs); + else + *frame = fs; + } return result; } diff --git a/libdw/unwind.h b/libdw/unwind.h index 687a94216..272ea9c20 100644 --- a/libdw/unwind.h +++ b/libdw/unwind.h @@ -2,7 +2,6 @@ #define _libdw_unwind_h 1 #include "libdw.h" -struct ebl; /* This describes one Common Information Entry read from a CFI section. Pointers here point into the DATA->d_buf block passed to dwarf_next_cfi. */ @@ -108,10 +107,6 @@ extern Dwarf_CFI *dwarf_getcfi_elf (Elf *elf); /* Release resources allocated by dwarf_getcfi_elf. */ extern int dwarf_cfi_end (Dwarf_CFI *cache); -/* Associate an open backend from with this Dwarf_CFI handle. - The backend may be required to perform CFI unwinding correctly. */ -extern int dwarf_cfi_setebl (Dwarf_CFI *cache, struct ebl *ebl); - /* Compute what's known about a call frame when the PC is at ADDRESS. Returns 0 for success or -1 for errors. @@ -171,7 +166,6 @@ extern int dwarf_frame_register (Dwarf_Frame *frame, int regno, /* Find the CFI for this module. Returns NULL if there is no CFI. On success, fills in *BIAS with the difference between addresses within the loaded module and those in the CFI referring to it. - This does dwarf_cfi_setebl for you, so another call is not required. The pointer returned can be used until the module is cleaned up. Calling this more than once returns the same pointer. */ extern Dwarf_CFI *dwfl_module_getcfi (Dwfl_Module *mod, Dwarf_Addr *bias); diff --git a/libdw/unwindP.h b/libdw/unwindP.h index 6b6fc03e3..432dbc742 100644 --- a/libdw/unwindP.h +++ b/libdw/unwindP.h @@ -244,7 +244,6 @@ INTDECL (dwarf_next_cfi) INTDECL (dwarf_getcfi) INTDECL (dwarf_getcfi_elf) INTDECL (dwarf_cfi_end) -INTDECL (dwarf_cfi_setebl) INTDECL (dwarf_cfi_addrframe) #endif /* unwindP.h */