From: Roland McGrath Date: Mon, 15 Aug 2005 09:53:48 +0000 (+0000) Subject: Add missing files X-Git-Tag: elfutils-0.120~113 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=104532fcdb87e769d8ebf5771b9c4370e4361a7b;p=thirdparty%2Felfutils.git Add missing files --- diff --git a/libdw/dwarf_func_die.c b/libdw/dwarf_func_die.c new file mode 100644 index 000000000..73c65d4d6 --- /dev/null +++ b/libdw/dwarf_func_die.c @@ -0,0 +1,27 @@ +/* Get definition DIE of function. + Copyright (C) 2005 Red Hat, Inc. + + This program is Open Source software; you can redistribute it and/or + modify it under the terms of the Open Software License version 1.0 as + published by the Open Source Initiative. + + You should have received a copy of the Open Software License along + with this program; if not, you may obtain a copy of the Open Software + License version 1.0 from http://www.opensource.org/licenses/osl.php or + by writing the Open Source Initiative c/o Lawrence Rosen, Esq., + 3001 King Ranch Road, Ukiah, CA 95482. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +Dwarf_Die * +dwarf_func_die (Dwarf_Func *func, Dwarf_Die *die_mem) +{ + *die_mem = *func->die; + return die_mem; +} diff --git a/libdw/dwarf_func_inline.c b/libdw/dwarf_func_inline.c new file mode 100644 index 000000000..7656286fc --- /dev/null +++ b/libdw/dwarf_func_inline.c @@ -0,0 +1,72 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + +struct visitor_info +{ + void *die_addr; + int (*callback) (Dwarf_Die *, void *); + void *arg; +}; + +static int +scope_visitor (unsigned int depth __attribute__ ((unused)), + Dwarf_Die *die, void *arg) +{ + struct visitor_info *const v = arg; + + if (INTUSE(dwarf_tag) (die) != DW_TAG_inlined_subroutine) + return DWARF_CB_OK; + + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_abstract_origin, + &attr_mem); + if (attr == NULL) + return DWARF_CB_OK; + + Dwarf_Die origin_mem; + Dwarf_Die *origin = INTUSE(dwarf_formref_die) (attr, &origin_mem); + if (origin == NULL) + return DWARF_CB_ABORT; + + if (origin->addr != v->die_addr) + return DWARF_CB_OK; + + return (*v->callback) (die, v->arg); +} + +int +dwarf_func_inline (Dwarf_Func *func) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word val; + if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr) (func->die, DW_AT_inline, + &attr_mem), + &val) == 0) + switch (val) + { + case DW_INL_not_inlined: + return 0; + + case DW_INL_declared_not_inlined: + return -1; + + case DW_INL_inlined: + case DW_INL_declared_inlined: + return 1; + } + + return 0; +} + +int +dwarf_func_inline_instances (Dwarf_Func *func, + int (*callback) (Dwarf_Die *, void *), + void *arg) +{ + struct visitor_info v = { func->die->addr, callback, arg }; + return __libdw_visit_scopes (0, func->cudie, &scope_visitor, &v); +} diff --git a/libdw/libdw_visit_scopes.c b/libdw/libdw_visit_scopes.c new file mode 100644 index 000000000..06168fb1b --- /dev/null +++ b/libdw/libdw_visit_scopes.c @@ -0,0 +1,104 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + +enum die_class { ignore, match, match_inline, walk, imported }; + +static enum die_class +classify_die (Dwarf_Die *die) +{ + switch (INTUSE(dwarf_tag) (die)) + { + /* DIEs with addresses we can try to match. */ + case DW_TAG_compile_unit: + case DW_TAG_module: + case DW_TAG_lexical_block: + case DW_TAG_with_stmt: + case DW_TAG_catch_block: + case DW_TAG_try_block: + case DW_TAG_entry_point: + return match; + case DW_TAG_inlined_subroutine: + return match_inline; + case DW_TAG_subprogram: + /* This might be a concrete out-of-line instance of an inline, in + which case it is not guaranteed to be owned by the right scope and + we will search for its origin as for DW_TAG_inlined_subroutine. */ + return (INTUSE(dwarf_hasattr) (die, DW_AT_abstract_origin) + ? match_inline : match); + + /* DIEs without addresses that can own DIEs with addresses. */ + case DW_TAG_namespace: + return walk; + + /* Special indirection required. */ + case DW_TAG_imported_unit: + return imported; + + /* Other DIEs we have no reason to descend. */ + default: + break; + } + return ignore; +} + +int +__libdw_visit_scopes (depth, root, visit, arg) + unsigned int depth; + Dwarf_Die *root; + int (*visit) (unsigned int depth, Dwarf_Die *die, void *arg); + void *arg; +{ + Dwarf_Die child; + if (INTUSE(dwarf_child) (root, &child) != 0) + return -1; + + do + { + int result = (*visit) (depth, &child, arg); + if (result != DWARF_CB_OK) + return result; + + switch (classify_die (&child)) + { + case match: + case match_inline: + case walk: + if (INTUSE(dwarf_haschildren) (&child)) + { + result = __libdw_visit_scopes (depth + 1, &child, visit, arg); + if (result != DWARF_CB_OK) + return result; + } + break; + + case imported: + { + /* This is imports another compilation unit to appear + as part of this one, inside the current scope. + Recurse to searesulth the referenced unit, but without + recording it as an inner scoping level. */ + + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child, DW_AT_import, + &attr_mem); + if (INTUSE(dwarf_formref_die) (attr, &child) != NULL) + { + result = __libdw_visit_scopes (depth + 1, &child, visit, arg); + if (result != 0) + return result; + } + } + break; + + default: + break; + } + } + while (INTUSE(dwarf_siblingof) (&child, &child) == 0); + + return 0; +}