]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Add locking to dwarf_getsrcfiles, dwarf_getsrclines, dwarf_macro_getsrcfiles
authorAaron Merey <amerey@redhat.com>
Mon, 17 Mar 2025 01:51:01 +0000 (21:51 -0400)
committerAaron Merey <amerey@redhat.com>
Wed, 26 Mar 2025 21:01:24 +0000 (17:01 -0400)
* libdw/dwarf_begin_elf.c (dwarf_begin_elf): Init macro_lock.
* libdw/dwarf_end.c (cu_free): Free src_lock.
(dwarf_end): Free macro_lock.
* libdw/dwarf_getsrcfiles.c (dwarf_getsrcfiles): Use src_lock.
* libdw/dwarf_getsrclines.c (dwarf_getsrclines): Ditto.
* libdw/dwarf_macro_getsrclines.c (dwarf_macro_getsrclines): Use
macro_lock.
* libdw/libdwP.h (struct Dwarf): Define macro_lock.
(struct Dwarf_CU): Define src_lock.
* libdw/libdw_findcu.c (__libdw_intern_next_unit): Init src_lock.

Signed-off-by: Aaron Merey <amerey@redhat.com>
libdw/dwarf_begin_elf.c
libdw/dwarf_end.c
libdw/dwarf_getsrcfiles.c
libdw/dwarf_getsrclines.c
libdw/dwarf_macro_getsrcfiles.c
libdw/libdwP.h
libdw/libdw_findcu.c

index 8a3a939bea3c23da8817e71c12e3a6c89638495c..58a309e9e7465a261b090525630a3ce7438e67f3 100644 (file)
@@ -580,6 +580,7 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
       return NULL;
     }
   mutex_init (result->dwarf_lock);
+  mutex_init (result->macro_lock);
   eu_search_tree_init (&result->cu_tree);
   eu_search_tree_init (&result->tu_tree);
   eu_search_tree_init (&result->split_tree);
index 92389c07ae4af65f72a6712c11aa82a62588543f..c12815e1004541223e4225f27ea61c49926efa7a 100644 (file)
@@ -70,6 +70,7 @@ cu_free (void *arg)
       Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
       rwlock_fini (p->abbrev_lock);
       rwlock_fini (p->split_lock);
+      mutex_fini (p->src_lock);
 
       /* Free split dwarf one way (from skeleton to split).  */
       if (p->unit_type == DW_UT_skeleton
@@ -130,6 +131,7 @@ dwarf_end (Dwarf *dwarf)
         free (dwarf->mem_tails);
       pthread_rwlock_destroy (&dwarf->mem_rwl);
       mutex_fini (dwarf->dwarf_lock);
+      mutex_fini (dwarf->macro_lock);
 
       /* Free the pubnames helper structure.  */
       free (dwarf->pubnames_sets);
index 24e4b7d287f622d2e0d8716073ffdcc588d6b328..9becd1d5fb6e121f9893493f3b449ccb13243047 100644 (file)
@@ -47,9 +47,10 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
     }
 
   int res = -1;
+  struct Dwarf_CU *const cu = cudie->cu;
+  mutex_lock (cudie->cu->src_lock);
 
   /* Get the information if it is not already known.  */
-  struct Dwarf_CU *const cu = cudie->cu;
   if (cu->files == NULL)
     {
       /* For split units there might be a simple file table (without lines).
@@ -96,7 +97,10 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
          Dwarf_Off debug_line_offset;
          if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
                               NULL, &debug_line_offset) == NULL)
-           return -1;
+           {
+             mutex_unlock (cudie->cu->src_lock);
+             return -1;
+           }
 
          res = __libdw_getsrcfiles (cu->dbg, debug_line_offset,
                                     __libdw_getcompdir (cudie),
@@ -115,8 +119,7 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
        *nfiles = cu->files->nfiles;
     }
 
-  // XXX Eventually: unlocking here.
-
+  mutex_unlock (cudie->cu->src_lock);
   return res;
 }
 INTDEF (dwarf_getsrcfiles)
index da78db67f3ae581839b430ffc7e8fca2a68df855..be10cdee005482d84b21c7a6260f80836aa0bcc1 100644 (file)
@@ -1442,8 +1442,10 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
       return -1;
     }
 
-  /* Get the information if it is not already known.  */
   struct Dwarf_CU *const cu = cudie->cu;
+  mutex_lock (cu->src_lock);
+
+  /* Get the information if it is not already known.  */
   if (cu->lines == NULL)
     {
       /* For split units always pick the lines from the skeleton.  */
@@ -1464,10 +1466,13 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
                  *lines = cu->lines;
                  *nlines = cu->lines->nlines;
                }
+
+             mutex_unlock (cu->src_lock);
              return res;
            }
 
          __libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
+         mutex_unlock (cu->src_lock);
          return -1;
        }
 
@@ -1485,21 +1490,29 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
       Dwarf_Off debug_line_offset;
       if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
                           NULL, &debug_line_offset) == NULL)
-       return -1;
+       {
+         mutex_unlock (cu->src_lock);
+         return -1;
+       }
 
       if (__libdw_getsrclines (cu->dbg, debug_line_offset,
                               __libdw_getcompdir (cudie),
                               cu->address_size, &cu->lines, &cu->files) < 0)
-       return -1;
+       {
+         mutex_unlock (cu->src_lock);
+         return -1;
+       }
     }
   else if (cu->lines == (void *) -1l)
-    return -1;
+    {
+      mutex_unlock (cu->src_lock);
+      return -1;
+    }
 
   *lines = cu->lines;
   *nlines = cu->lines->nlines;
 
-  // XXX Eventually: unlocking here.
-
+  mutex_unlock (cu->src_lock);
   return 0;
 }
 INTDEF(dwarf_getsrclines)
index 5e02935d405e7b92bb7f3136d3d4357d857cda1e..6ccbeadb29faf4a17b4d9ea4a6eaecd7104d961c 100644 (file)
@@ -41,6 +41,8 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
 
   /* macro is declared NN */
   Dwarf_Macro_Op_Table *const table = macro->table;
+
+  mutex_lock (table->dbg->macro_lock);
   if (table->files == NULL)
     {
       Dwarf_Off line_offset = table->line_offset;
@@ -48,6 +50,7 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
        {
          *files = NULL;
          *nfiles = 0;
+         mutex_unlock (table->dbg->macro_lock);
          return 0;
        }
 
@@ -80,9 +83,14 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
     }
 
   if (table->files == (void *) -1)
-    return -1;
+    {
+      mutex_unlock (table->dbg->macro_lock);
+      return -1;
+    }
 
   *files = table->files;
   *nfiles = table->files->nfiles;
+
+  mutex_unlock (table->dbg->macro_lock);
   return 0;
 }
index a9d4c0a7c5a12bce7be9abc602c0ce2413f2352f..3216f2a1dd724fb7365018a7a1bcc4f7085b4016 100644 (file)
@@ -265,11 +265,13 @@ struct Dwarf
   pthread_rwlock_t mem_rwl;
 
   /* Recursive mutex intended for setting/getting alt_dwarf, next_tu_offset,
-     and next_cu_offset.  Covers dwarf_getsrclines, dwarf_getsrcfiles and
-     dwarf_macro_getsrcfiles.  Should also be held when calling
+     and next_cu_offset.  Should be held when calling
      __libdw_intern_next_unit.  */
   mutex_define(, dwarf_lock);
 
+  /* Synchronize access to dwarf_macro_getsrcfiles.  */
+  mutex_define(, macro_lock);
+
   /* Internal memory handling.  This is basically a simplified thread-local
      reimplementation of obstacks.  Unfortunately the standard obstack
      implementation is not usable in libraries.  */
@@ -461,6 +463,10 @@ struct Dwarf_CU
      Covers __libdw_find_split_unit.  */
   rwlock_define(, split_lock);
 
+  /* Synchronize access to the lines and files members.
+     Covers dwarf_getsrclines and dwarf_getsrcfiles.  */
+  mutex_define(, src_lock);
+
   /* Memory boundaries of this CU.  */
   void *startp;
   void *endp;
index 613f61c89622f6316cabb3e53e8dc44e15fc0d7d..f02436434321bbc71fe344afea0d77ff08c4f05e 100644 (file)
@@ -179,6 +179,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
   eu_search_tree_init (&newp->locs_tree);
   rwlock_init (newp->abbrev_lock);
   rwlock_init (newp->split_lock);
+  mutex_init (newp->src_lock);
 
   /* v4 debug type units have version == 4 and unit_type == DW_UT_type.  */
   if (debug_types)