]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Add missing files
authorRoland McGrath <roland@redhat.com>
Mon, 15 Aug 2005 09:53:48 +0000 (09:53 +0000)
committerRoland McGrath <roland@redhat.com>
Mon, 15 Aug 2005 09:53:48 +0000 (09:53 +0000)
libdw/dwarf_func_die.c [new file with mode: 0644]
libdw/dwarf_func_inline.c [new file with mode: 0644]
libdw/libdw_visit_scopes.c [new file with mode: 0644]

diff --git a/libdw/dwarf_func_die.c b/libdw/dwarf_func_die.c
new file mode 100644 (file)
index 0000000..73c65d4
--- /dev/null
@@ -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 <config.h>
+#endif
+
+#include <dwarf.h>
+#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 (file)
index 0000000..7656286
--- /dev/null
@@ -0,0 +1,72 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+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 (file)
index 0000000..06168fb
--- /dev/null
@@ -0,0 +1,104 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+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;
+}