]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: unify die->abbrev lookups
authorJosh Stone <jistone@redhat.com>
Thu, 11 Dec 2014 02:28:04 +0000 (18:28 -0800)
committerJosh Stone <jistone@redhat.com>
Thu, 11 Dec 2014 19:23:26 +0000 (11:23 -0800)
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
libdw/dwarf_child.c
libdw/dwarf_getattrs.c
libdw/dwarf_haschildren.c
libdw/dwarf_tag.c
libdw/libdwP.h

index b9b868b5c01e8081f01d352eaef8ee91b12569d5..0d3150b91845e3efbb0c685d7fbd3e2ab0addb3a 100644 (file)
@@ -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-04  Mark Wielaard  <mjw@redhat.com>
 
        * libdwP.h (__libdw_form_val_compute_len): Add endp argument.
index fa316006636c0acad650fe00ebeafe477c8b9e27..daf4c26564723e07921baf414f4bb4d05283f820 100644 (file)
@@ -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.  */
@@ -137,21 +127,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;
 
index 627a85118d05e98918fddb9a45083adc4d89e9f4..9ea70fca4068163137e44267d46312040cafd69b 100644 (file)
@@ -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;
@@ -105,7 +100,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).  */
index b2273982957864eba448db6a1481dc4b8e08a471..d0ce51ea314c4aa19419c2e89c044eff4f88b784 100644 (file)
@@ -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)
index ff012cf4265c02feef03945cc855ccf02816c588..0b1a4b086a6c0de1e9a82d748f9cc48240050b46 100644 (file)
@@ -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)
index 351c5b47b7564ec8cd5ae276f95167ad839c13f2..0633853966d44fca6aeb7d4661e60390390f7c66 100644 (file)
@@ -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,29 @@ extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
                                        Dwarf_Abbrev *result)
      __nonnull_attribute__ (1) internal_function;
 
+/* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
+   just past the abbreviation code.  */
+static inline Dwarf_Abbrev *
+__nonnull_attribute__ (1)
+__libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
+{
+  /* Do we 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,