Branch data Line data Source code
1 : : /* Convenience functions for handling DWARF descriptions of inline functions. 2 : : Copyright (C) 2005,2006,2015 Red Hat, Inc. 3 : : This file is part of elfutils. 4 : : 5 : : This file is free software; you can redistribute it and/or modify 6 : : it under the terms of either 7 : : 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 11 : : 12 : : or 13 : : 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 17 : : 18 : : or both in parallel, as here. 19 : : 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. 24 : : 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/>. */ 28 : : 29 : : #ifdef HAVE_CONFIG_H 30 : : # include <config.h> 31 : : #endif 32 : : 33 : : #include "libdwP.h" 34 : : #include <dwarf.h> 35 : : 36 : : struct visitor_info 37 : : { 38 : : void *die_addr; 39 : : int (*callback) (Dwarf_Die *, void *); 40 : : void *arg; 41 : : }; 42 : : 43 : : static int 44 : 1920510 : scope_visitor (unsigned int depth __attribute__ ((unused)), 45 : : struct Dwarf_Die_Chain *die, void *arg) 46 : : { 47 : 1920510 : struct visitor_info *const v = arg; 48 : : 49 [ + + ]: 1920510 : if (INTUSE(dwarf_tag) (&die->die) != DW_TAG_inlined_subroutine) 50 : : return DWARF_CB_OK; 51 : : 52 : 100704 : Dwarf_Attribute attr_mem; 53 : 100704 : Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&die->die, DW_AT_abstract_origin, 54 : : &attr_mem); 55 [ - + ]: 100704 : if (attr == NULL) 56 : : return DWARF_CB_OK; 57 : : 58 : 100704 : Dwarf_Die origin_mem; 59 : 100704 : Dwarf_Die *origin = INTUSE(dwarf_formref_die) (attr, &origin_mem); 60 [ + - ]: 100704 : if (origin == NULL) 61 : : return DWARF_CB_ABORT; 62 : : 63 [ + + ]: 100704 : if (origin->addr != v->die_addr) 64 : : return DWARF_CB_OK; 65 : : 66 : 7391 : return (*v->callback) (&die->die, v->arg); 67 : : } 68 : : 69 : : int 70 : 5821 : dwarf_func_inline (Dwarf_Die *func) 71 : : { 72 : 5821 : Dwarf_Attribute attr_mem; 73 : 5821 : Dwarf_Word val; 74 [ + + ]: 5821 : if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr) (func, DW_AT_inline, 75 : : &attr_mem), 76 : : &val) == 0) 77 [ - + ]: 2521 : switch (val) 78 : : { 79 : : case DW_INL_not_inlined: 80 : : return 0; 81 : : 82 : : case DW_INL_declared_not_inlined: 83 : : return -1; 84 : : 85 : : case DW_INL_inlined: 86 : : case DW_INL_declared_inlined: 87 : : return 1; 88 : : } 89 : : 90 : : return 0; 91 : : } 92 : : 93 : : int 94 : 2506 : dwarf_func_inline_instances (Dwarf_Die *func, 95 : : int (*callback) (Dwarf_Die *, void *), 96 : : void *arg) 97 : : { 98 : 2506 : struct visitor_info v = { func->addr, callback, arg }; 99 : 2506 : struct Dwarf_Die_Chain cu = { .die = CUDIE (func->cu), .parent = NULL }; 100 : 2506 : return __libdw_visit_scopes (0, &cu, NULL, &scope_visitor, NULL, &v); 101 : : }