]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwP.h: Add locking to __libdw_dieabbrev
authorAaron Merey <amerey@redhat.com>
Tue, 16 Jul 2024 16:25:57 +0000 (12:25 -0400)
committerAaron Merey <amerey@redhat.com>
Tue, 16 Jul 2024 20:22:36 +0000 (16:22 -0400)
        * libdw/libdwP.h (__libdw_dieabbrev): Add locking.
        (struct Dwarf): Add dwarf_lock.
        (struct Dwarf_CU): Add abbrev_lock, 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>
v2 changes:
This replaces patch "libdw: Add locking around __libdw_dieabbrev for
dwarf_hasattr".  Mark suggested that we remove lazy abbrev reading
in order to simplify the locking of __libdw_dieabbrev.  This is
a fair bit of work so for now lets just put a write lock around all
of __libdw_dieabbrev.  The removal of lazy reading of abbrev will be
done in a future patch.

libdw/dwarf_formref_die.c
libdw/dwarf_setalt.c
libdw/libdwP.h

index 48ba819422d534dc8d30cb7e9d4807cb82afd4e0..f8a51970cc5af659ace49671330de0025a6e506c 100644 (file)
@@ -92,7 +92,9 @@ 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 dc9b61cb0f355d60550c8ae486fce696d45e483b..f7d70d9dc3799a86604cd2848bda25825b7a9d11 100644 (file)
@@ -35,6 +35,8 @@
 void
 dwarf_setalt (Dwarf *main, Dwarf *alt)
 {
+  rwlock_wrlock(main->dwarf_lock);
+
   if (main->alt_fd != -1)
     {
       INTUSE(dwarf_end) (main->alt_dwarf);
@@ -43,5 +45,7 @@ dwarf_setalt (Dwarf *main, Dwarf *alt)
     }
 
   main->alt_dwarf = alt;
+
+  rwlock_unlock(main->dwarf_lock);
 }
 INTDEF (dwarf_setalt)
index a4f26b8231fca893ab5e700016269b8d8dd6a1fa..9dce10e5603663fe0c9d22da515071f2120ea55d 100644 (file)
@@ -804,15 +804,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;
@@ -821,7 +834,9 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
       if (die->abbrev == NULL)
        die->abbrev = __libdw_findabbrev (die->cu, code);
     }
-  return die->abbrev;
+
+  rwlock_unlock (die->cu->abbrev_lock);
+  return (Dwarf_Abbrev *) die->abbrev;
 }
 
 /* Helper functions for form handling.  */