summaryrefslogtreecommitdiff
path: root/libdw/dwarf_getscopes_die.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdw/dwarf_getscopes_die.c')
-rw-r--r--libdw/dwarf_getscopes_die.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/libdw/dwarf_getscopes_die.c b/libdw/dwarf_getscopes_die.c
new file mode 100644
index 00000000..bdcee354
--- /dev/null
+++ b/libdw/dwarf_getscopes_die.c
@@ -0,0 +1,69 @@
+/* Return scope DIEs containing given DIE.
+ 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 "libdwP.h"
+#include <assert.h>
+#include <stdlib.h>
+
+static int
+scope_visitor (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg)
+{
+ if (die->die.addr != *(void **) arg)
+ return 0;
+
+ Dwarf_Die *scopes = malloc (depth * sizeof scopes[0]);
+ if (scopes == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return -1;
+ }
+
+ unsigned int i = 0;
+ do
+ {
+ scopes[i++] = die->die;
+ die = die->parent;
+ }
+ while (die != NULL);
+ assert (i == depth);
+
+ *(void **) arg = scopes;
+ return depth;
+}
+
+int
+dwarf_getscopes_die (Dwarf_Die *die, Dwarf_Die **scopes)
+{
+ if (die == NULL)
+ return -1;
+
+ struct Dwarf_Die_Chain cu =
+ {
+ .parent = NULL,
+ .die =
+ {
+ .cu = die->cu,
+ .addr = ((char *) die->cu->dbg->sectiondata[IDX_debug_info]->d_buf
+ + die->cu->start + 3 * die->cu->offset_size - 4 + 3),
+ }
+ };
+
+ void *info = die->addr;
+ int result = __libdw_visit_scopes (1, &cu, &scope_visitor, NULL, &info);
+ if (result > 0)
+ *scopes = info;
+ return result;
+}