This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/3] libdw: unify die->abbrev lookups


Add a new internal function, __libdw_dieabbrev, which deals with checking
a die for an abbrev, and setting it as needed.

Signed-off-by: Josh Stone <jistone@redhat.com>
---
 libdw/ChangeLog           |  8 ++++++++
 libdw/dwarf_child.c       | 44 +++++++++++++++++---------------------------
 libdw/dwarf_getattrs.c    | 21 ++++++++-------------
 libdw/dwarf_haschildren.c | 20 ++++----------------
 libdw/dwarf_tag.c         | 20 +++++---------------
 libdw/libdwP.h            | 24 +++++++++++++++++++++++-
 6 files changed, 65 insertions(+), 72 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 909fdbc1f8fe..a2a4e1d49747 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,11 @@
+2014-12-10  Josh Stone  <jistone@redhat.com>
+
+	* libdwP.h (__libdw_dieabbrev): New die->abbrev lookup function.
+	* dwarf_child.c (__libdw_find_attr, dwarf_child): Use it.
+	* dwarf_getattrs.c (dwarf_getattrs): Likewise.
+	* dwarf_haschildren.c (dwarf_haschildren): Likewise.
+	* dwarf_tag.c (dwarf_tag): Likewise.
+
 2014-12-02  Petr Machata  <pmachata@redhat.com>
 
 	* dwarf_getmacros.c (token_from_offset, offset_from_token): New
diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c
index 1d3a337171a8..3e88fedf1df7 100644
--- a/libdw/dwarf_child.c
+++ b/libdw/dwarf_child.c
@@ -1,5 +1,5 @@
 /* Return child of current DIE.
-   Copyright (C) 2003-2011 Red Hat, Inc.
+   Copyright (C) 2003-2011, 2014 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -44,21 +44,11 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
 		   unsigned int *codep, unsigned int *formp)
 {
   Dwarf *dbg = die->cu->dbg;
-  const unsigned char *readp = (unsigned char *) die->addr;
-
-  /* First we have to get the abbreviation code so that we can decode
-     the data in the DIE.  */
-  unsigned int abbrev_code;
-  get_uleb128 (abbrev_code, readp);
+  const unsigned char *readp;
 
   /* Find the abbreviation entry.  */
-  Dwarf_Abbrev *abbrevp = die->abbrev;
-  if (abbrevp == NULL)
-    {
-      abbrevp = __libdw_findabbrev (die->cu, abbrev_code);
-      die->abbrev = abbrevp ?: DWARF_END_ABBREV;
-    }
-  if (unlikely (die->abbrev == DWARF_END_ABBREV))
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &readp);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
     {
     invalid_dwarf:
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
@@ -70,7 +60,7 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
     = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
        + dbg->sectiondata[IDX_debug_abbrev]->d_size);
 
-  const unsigned char *attrp = die->abbrev->attrp;
+  const unsigned char *attrp = abbrevp->attrp;
   while (1)
     {
       /* Are we still in bounds?  This test needs to be refined.  */
@@ -136,21 +126,21 @@ dwarf_child (die, result)
   if (die == NULL)
     return -1;
 
-  /* Skip past the last attribute.  */
-  void *addr = NULL;
-
-  /* If we already know there are no children do not search.  */
-  if (die->abbrev != DWARF_END_ABBREV
-      && (die->abbrev == NULL || die->abbrev->has_children))
-    addr = __libdw_find_attr (die, INVALID, NULL, NULL);
-  if (unlikely (die->abbrev == (Dwarf_Abbrev *) -1l))
-    return -1;
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
 
-  /* Make sure the DIE really has children.  */
-  if (! die->abbrev->has_children)
-    /* There cannot be any children.  */
+  /* If there are no children, do not search.  */
+  if (! abbrevp->has_children)
     return 1;
 
+  /* Skip past the last attribute.  */
+  void *addr = __libdw_find_attr (die, INVALID, NULL, NULL);
+
   if (addr == NULL)
     return -1;
 
diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c
index 82eb3f8faa1e..786a3e670224 100644
--- a/libdw/dwarf_getattrs.c
+++ b/libdw/dwarf_getattrs.c
@@ -1,5 +1,5 @@
 /* Get attributes of the DIE.
-   Copyright (C) 2004, 2005, 2008, 2009 Red Hat, Inc.
+   Copyright (C) 2004, 2005, 2008, 2009, 2014 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -44,17 +44,12 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
   if (unlikely (offset == 1))
     return 1;
 
-  const unsigned char *die_addr = die->addr;
+  const unsigned char *die_addr;
 
-  /* Get the abbreviation code.  */
-  unsigned int u128;
-  get_uleb128 (u128, die_addr);
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &die_addr);
 
-  if (die->abbrev == NULL)
-    /* Find the abbreviation.  */
-    die->abbrev = __libdw_findabbrev (die->cu, u128);
-
-  if (unlikely (die->abbrev == DWARF_END_ABBREV))
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
     {
     invalid_dwarf:
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
@@ -62,8 +57,8 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
     }
 
   /* This is where the attributes start.  */
-  const unsigned char *attrp = die->abbrev->attrp;
-  const unsigned char *const offset_attrp = die->abbrev->attrp + offset;
+  const unsigned char *attrp = abbrevp->attrp;
+  const unsigned char *const offset_attrp = abbrevp->attrp + offset;
 
   /* Go over the list of attributes.  */
   Dwarf *dbg = die->cu->dbg;
@@ -104,7 +99,7 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
 	    /* Return the offset of the start of the attribute, so that
 	       dwarf_getattrs() can be restarted from this point if the
 	       caller so desires.  */
-	    return remembered_attrp - die->abbrev->attrp;
+	    return remembered_attrp - abbrevp->attrp;
 	}
 
       /* Skip over the rest of this attribute (if there is any).  */
diff --git a/libdw/dwarf_haschildren.c b/libdw/dwarf_haschildren.c
index b22739829578..d0ce51ea314c 100644
--- a/libdw/dwarf_haschildren.c
+++ b/libdw/dwarf_haschildren.c
@@ -1,5 +1,5 @@
 /* Return string associated with given attribute.
-   Copyright (C) 2003, 2005, 2008 Red Hat, Inc.
+   Copyright (C) 2003, 2005, 2008, 2014 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -40,25 +40,13 @@ dwarf_haschildren (die)
      Dwarf_Die *die;
 {
   /* Find the abbreviation entry.  */
-  Dwarf_Abbrev *abbrevp = die->abbrev;
-  if (abbrevp != DWARF_END_ABBREV)
-    {
-      const unsigned char *readp = (unsigned char *) die->addr;
-
-      /* First we have to get the abbreviation code so that we can decode
-	 the data in the DIE.  */
-      unsigned int abbrev_code;
-      get_uleb128 (abbrev_code, readp);
-
-      abbrevp = __libdw_findabbrev (die->cu, abbrev_code);
-      die->abbrev = abbrevp ?: DWARF_END_ABBREV;
-    }
-  if (unlikely (die->abbrev == DWARF_END_ABBREV))
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
     {
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
       return -1;
     }
 
-  return die->abbrev->has_children;
+  return abbrevp->has_children;
 }
 INTDEF (dwarf_haschildren)
diff --git a/libdw/dwarf_tag.c b/libdw/dwarf_tag.c
index ff012cf4265c..0b1a4b086a6c 100644
--- a/libdw/dwarf_tag.c
+++ b/libdw/dwarf_tag.c
@@ -1,5 +1,5 @@
 /* Return tag of given DIE.
-   Copyright (C) 2003-2011 Red Hat, Inc.
+   Copyright (C) 2003-2011, 2014 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -82,24 +82,14 @@ int
 dwarf_tag (die)
      Dwarf_Die *die;
 {
-  /* Do we already know the abbreviation?  */
-  if (die->abbrev == NULL)
-    {
-      /* Get the abbreviation code.  */
-      unsigned int u128;
-      const unsigned char *addr = die->addr;
-      get_uleb128 (u128, addr);
-
-      /* Find the abbreviation.  */
-      die->abbrev = __libdw_findabbrev (die->cu, u128);
-    }
-
-  if (unlikely (die->abbrev == DWARF_END_ABBREV))
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
     {
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
       return DW_TAG_invalid;
     }
 
-  return die->abbrev->tag;
+  return abbrevp->tag;
 }
 INTDEF(dwarf_tag)
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 5ccb13c4bc83..f391c94ed647 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -444,7 +444,7 @@ extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
      __nonnull_attribute__ (1) internal_function;
 
-/* Return tag of given DIE.  */
+/* Get abbreviation with given code.  */
 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
 					 unsigned int code)
      __nonnull_attribute__ (1) internal_function;
@@ -455,6 +455,28 @@ extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
 					Dwarf_Abbrev *result)
      __nonnull_attribute__ (1) internal_function;
 
+/* Get abbreviation of given DIE.  */
+static inline Dwarf_Abbrev *
+__nonnull_attribute__ (1)
+__libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
+{
+  /* Do need to get the abbreviation, or need to read after the code?  */
+  if (die->abbrev == NULL || readp != NULL)
+    {
+      /* Get the abbreviation code.  */
+      unsigned int code;
+      const unsigned char *addr = die->addr;
+      get_uleb128 (code, addr);
+      if (readp != NULL)
+	*readp = addr;
+
+      /* Find the abbreviation.  */
+      if (die->abbrev == NULL)
+	die->abbrev = __libdw_findabbrev (die->cu, code);
+    }
+  return die->abbrev;
+}
+
 /* Helper functions for form handling.  */
 extern size_t __libdw_form_val_compute_len (Dwarf *dbg, struct Dwarf_CU *cu,
 					    unsigned int form,
-- 
2.1.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]