summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_getscopes.c
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2007-08-07 19:51:01 +0000
committerRoland McGrath <[email protected]>2007-08-07 19:51:01 +0000
commitd1a4817e7d913efbaa7d4f4462949ed7b53618b3 (patch)
tree2992ea4eed483e4297ac706e5596da56bd81cde4 /libdw/dwarf_getscopes.c
parentc98bcc796529b7ec56f369c743748d9ff32abf61 (diff)
2007-08-07 Roland McGrath <[email protected]>
* dwarf_getscopes.c (pc_match): Swallow dwarf_haspc error return when error code is DWARF_E_NOERROR (0).
Diffstat (limited to 'libdw/dwarf_getscopes.c')
-rw-r--r--libdw/dwarf_getscopes.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/libdw/dwarf_getscopes.c b/libdw/dwarf_getscopes.c
index f9fa5132..73431ba7 100644
--- a/libdw/dwarf_getscopes.c
+++ b/libdw/dwarf_getscopes.c
@@ -1,5 +1,5 @@
/* Return scope DIEs containing PC address.
- Copyright (C) 2005 Red Hat, Inc.
+ Copyright (C) 2005, 2007 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -71,10 +71,32 @@ pc_match (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg)
{
struct args *a = arg;
- if (a->scopes != NULL || INTUSE(dwarf_haspc) (&die->die, a->pc) <= 0)
+ if (a->scopes != NULL)
die->prune = true;
- else if (INTUSE (dwarf_tag) (&die->die) == DW_TAG_inlined_subroutine)
- a->inlined = depth;
+ else
+ {
+ /* dwarf_haspc returns an error if there are no appropriate attributes.
+ But we use it indiscriminantly instead of presuming which tags can
+ have PC attributes. So when it fails for that reason, treat it just
+ as a nonmatching return. */
+ int result = INTUSE(dwarf_haspc) (&die->die, a->pc);
+ if (result < 0)
+ {
+ int error = INTUSE(dwarf_errno) ();
+ if (error != DWARF_E_NOERROR && error != DWARF_E_NO_DEBUG_RANGES)
+ {
+ __libdw_seterrno (error);
+ return -1;
+ }
+ result = 0;
+ }
+ if (result == 0)
+ die->prune = true;
+
+ if (!die->prune
+ && INTUSE (dwarf_tag) (&die->die) == DW_TAG_inlined_subroutine)
+ a->inlined = depth;
+ }
return 0;
}
@@ -119,11 +141,11 @@ pc_record (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg)
{
struct args *a = arg;
+ if (die->prune)
+ return 0;
+
if (a->scopes == NULL)
{
- if (die->prune)
- return 0;
-
/* We have hit the innermost DIE that contains the target PC. */
a->nscopes = depth + 1 - a->inlined;
@@ -175,7 +197,7 @@ pc_record (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg)
If we don't find it, return to search the containing scope.
If we do find it, the nonzero return value will bail us out
of the postorder traversal. */
- return __libdw_visit_scopes (depth, die, &origin_match, NULL, &a);
+ return __libdw_visit_scopes (depth, die, &origin_match, NULL, a);
}