]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwP.h: Add locking to __libdw_dieabbrev
authorHeather McIntyre <hsm2@rice.edu>
Tue, 16 Jul 2024 16:25:57 +0000 (12:25 -0400)
committerAaron Merey <amerey@redhat.com>
Wed, 21 Aug 2024 00:19:13 +0000 (20:19 -0400)
* libdw/dwarf_end.c (cu_free): Free abbrev_lock.
        * libdw/libdwP.h (__libdw_dieabbrev): Add locking.
  (struct Dwarf_CU): Define abbrev_lock.
* libdw/libdw_findcu.c (__libdw_intern_next_unit): Init
  abbrev_lock.

Signed-off-by: Heather S. McIntyre <hsm2@rice.edu>
Signed-off-by: Aaron Merey <amerey@redhat.com>
Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/dwarf_end.c
libdw/libdwP.h
libdw/libdw_findcu.c

index eaa97050b56b2707ee7e4d4213e8c6fb5b23cc8b..487d6ce72d3a5e97070110cfc43396c8aaec8cd9 100644 (file)
@@ -68,6 +68,7 @@ cu_free (void *arg)
      && p != p->dbg->fake_addr_cu)
     {
       Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
+      rwlock_fini (p->abbrev_lock);
 
       /* Free split dwarf one way (from skeleton to split).  */
       if (p->unit_type == DW_UT_skeleton
index 85b4e01ad54e5605229d124d87c15456a8c6e0f8..8ba87463c4dcb0462725b7fa111a1b197df4de9a 100644 (file)
@@ -451,6 +451,10 @@ struct Dwarf_CU
      Don't access directly, call __libdw_cu_locs_base.  */
   Dwarf_Off locs_base;
 
+  /* Synchronize access to the abbrev member of a Dwarf_Die that
+     refers to this Dwarf_CU.  */
+  rwlock_define(, abbrev_lock);
+
   /* Memory boundaries of this CU.  */
   void *startp;
   void *endp;
@@ -798,15 +802,28 @@ static inline Dwarf_Abbrev *
 __nonnull_attribute__ (1)
 __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
 {
+  if (unlikely (die->cu == NULL))
+    {
+      die->abbrev = DWARF_END_ABBREV;
+      return DWARF_END_ABBREV;
+    }
+
+  rwlock_wrlock (die->cu->abbrev_lock);
+
   /* 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;
-      if (unlikely (die->cu == NULL
-                   || addr >= (const unsigned char *) die->cu->endp))
-       return die->abbrev = DWARF_END_ABBREV;
+
+      if (addr >= (const unsigned char *) die->cu->endp)
+       {
+         die->abbrev = DWARF_END_ABBREV;
+         rwlock_unlock (die->cu->abbrev_lock);
+         return DWARF_END_ABBREV;
+       }
+
       get_uleb128 (code, addr, die->cu->endp);
       if (readp != NULL)
        *readp = addr;
@@ -815,7 +832,11 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
       if (die->abbrev == NULL)
        die->abbrev = __libdw_findabbrev (die->cu, code);
     }
-  return die->abbrev;
+
+  Dwarf_Abbrev *result = die->abbrev;
+  rwlock_unlock (die->cu->abbrev_lock);
+
+  return result;
 }
 
 /* Helper functions for form handling.  */
index bfbad41067cea9824b0a8a25aa647e83ac69c8f9..0f46d77713264c509f0e9d3065254310c0364451 100644 (file)
@@ -177,6 +177,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
   newp->startp = data->d_buf + newp->start;
   newp->endp = data->d_buf + newp->end;
   eu_search_tree_init (&newp->locs_tree);
+  rwlock_init (newp->abbrev_lock);
 
   /* v4 debug type units have version == 4 and unit_type == DW_UT_type.  */
   if (debug_types)