]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Make libdw_find_split_unit thread-safe
authorHeather McIntyre <hsm2@rice.edu>
Tue, 20 Aug 2024 20:42:03 +0000 (16:42 -0400)
committerAaron Merey <amerey@redhat.com>
Wed, 21 Aug 2024 00:19:13 +0000 (20:19 -0400)
* libdw/dwarf_end.c (cu_free): Free split_lock.
* libdw/dwarf_formref_die.c (dwarf_formref_die): Add locking
  around call to __libdw_intern_next_unit.
* libdw/libdwP.h (struct Dwarf_CU): Add split_lock.
* libdw/libdw_find_split_unit.c (__libdw_find_split_unit):
  Add locking.
* libdw/libdw_findcu.c (__libdw_intern_next_unit): Init
  split_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/dwarf_formref_die.c
libdw/libdwP.h
libdw/libdw_find_split_unit.c
libdw/libdw_findcu.c

index 487d6ce72d3a5e97070110cfc43396c8aaec8cd9..ee3ed74e355821148c46c5e481dba839e5441a76 100644 (file)
@@ -69,6 +69,7 @@ cu_free (void *arg)
     {
       Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
       rwlock_fini (p->abbrev_lock);
+      rwlock_fini (p->split_lock);
 
       /* Free split dwarf one way (from skeleton to split).  */
       if (p->unit_type == DW_UT_skeleton
index 48ba819422d534dc8d30cb7e9d4807cb82afd4e0..69d1bf1cf54fddba0d831970c2b435590c49d080 100644 (file)
@@ -92,7 +92,10 @@ dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *result)
          bool scan_debug_types = false;
          do
            {
+             rwlock_wrlock(attr->cu->dbg->dwarf_lock);
              cu = __libdw_intern_next_unit (attr->cu->dbg, scan_debug_types);
+             rwlock_unlock(attr->cu->dbg->dwarf_lock);
+
              if (cu == NULL)
                {
                  if (scan_debug_types == false)
index 8ba87463c4dcb0462725b7fa111a1b197df4de9a..d6bab6063cca74de4c23d6c5a542d773e55bac5d 100644 (file)
@@ -455,6 +455,9 @@ struct Dwarf_CU
      refers to this Dwarf_CU.  */
   rwlock_define(, abbrev_lock);
 
+  /* Synchronize access to the split member of this Dwarf_CU.  */
+  rwlock_define(, split_lock);
+
   /* Memory boundaries of this CU.  */
   void *startp;
   void *endp;
index 4005793b918a679d134877e45d4793db337a035c..f4f34c5d9622fe5cd02be5273729a975c37a62e7 100644 (file)
@@ -150,9 +150,18 @@ Dwarf_CU *
 internal_function
 __libdw_find_split_unit (Dwarf_CU *cu)
 {
+  /* Set result before releasing the lock.  */
+  Dwarf_CU *result;
+
+  rwlock_wrlock(cu->split_lock);
+
   /* Only try once.  */
   if (cu->split != (Dwarf_CU *) -1)
-    return cu->split;
+    {
+      result = cu->split;
+      rwlock_unlock(cu->split_lock);
+      return result;
+    }
 
   /* We need a skeleton unit with a comp_dir and [GNU_]dwo_name attributes.
      The split unit will be the first in the dwo file and should have the
@@ -207,5 +216,7 @@ __libdw_find_split_unit (Dwarf_CU *cu)
   if (cu->split == (Dwarf_CU *) -1)
     cu->split = NULL;
 
-  return cu->split;
+  result = cu->split;
+  rwlock_unlock(cu->split_lock);
+  return result;
 }
index 0f46d77713264c509f0e9d3065254310c0364451..c74e895e16bd0754e7a511141973d640e9e37554 100644 (file)
@@ -178,6 +178,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
   newp->endp = data->d_buf + newp->end;
   eu_search_tree_init (&newp->locs_tree);
   rwlock_init (newp->abbrev_lock);
+  rwlock_init (newp->split_lock);
 
   /* v4 debug type units have version == 4 and unit_type == DW_UT_type.  */
   if (debug_types)