]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
thread safety v2 WIP
authorAaron Merey <amerey@redhat.com>
Wed, 26 Jun 2024 21:17:05 +0000 (17:17 -0400)
committerAaron Merey <amerey@redhat.com>
Wed, 26 Jun 2024 21:17:05 +0000 (17:17 -0400)
33 files changed:
lib/eu-config.h
lib/eu-search.c
lib/eu-search.h
libcpu/i386_parse.y
libdw/cfi.h
libdw/cie.c
libdw/dwarf_begin_elf.c
libdw/dwarf_end.c
libdw/dwarf_formref_die.c
libdw/dwarf_getalt.c
libdw/dwarf_getcfi.c
libdw/dwarf_getlocation.c
libdw/dwarf_getmacros.c
libdw/dwarf_getsrclines.c
libdw/dwarf_hasattr.c
libdw/dwarf_setalt.c
libdw/fde.c
libdw/frame-cache.c
libdw/libdw.h
libdw/libdwP.h
libdw/libdw_find_split_unit.c
libdw/libdw_findcu.c
libdwfl/cu.c
libdwfl/dwfl_module.c
libdwfl/libdwflP.h
libelf/common.h
libelf/elf_begin.c
libelf/elf_cntl.c
libelf/elf_end.c
libelf/elf_getdata_rawchunk.c
libelf/elf_readall.c
libelf/libelfP.h
tests/.Makefile.am.rej.swp [deleted file]

index feb079dbc2f6d999f000423a8ff7ac92f99854da..0b9f03421fd5173f68f7621ed9556ce2c9c9e4db 100644 (file)
@@ -29,6 +29,8 @@
 #ifndef EU_CONFIG_H
 #define EU_CONFIG_H    1
 
+#include <stdio.h>
+
 #ifdef USE_LOCKS
 # include <pthread.h>
 # include <assert.h>
   ({ int _err = pthread_ ## call; assert_perror (_err); })
 # define rwlock_init(lock)             RWLOCK_CALL (init (&lock, NULL))
 # define rwlock_fini(lock)             RWLOCK_CALL (destroy (&lock))
-# define rwlock_rdlock(lock)           RWLOCK_CALL (rdlock (&lock))
-# define rwlock_wrlock(lock)           RWLOCK_CALL (wrlock (&lock))
-# define rwlock_unlock(lock)           RWLOCK_CALL (unlock (&lock))
+
+# define rwlock_rdlock(lock)            RWLOCK_CALL (rdlock (&lock))
+# define rwlock_wrlock(lock)            RWLOCK_CALL (wrlock (&lock))
+# define rwlock_unlock(lock)            RWLOCK_CALL (unlock (&lock))
+
+//# define rwlock_rdlock(lock)         ({ printf ("rw locking %lx\n", (unsigned long) &lock); fflush(NULL); RWLOCK_CALL (rdlock (&lock)); })
+//# define rwlock_wrlock(lock)         ({ printf ("wr locking %lx\n", (unsigned long) &lock); fflush(NULL); RWLOCK_CALL (wrlock (&lock)); })
+//# define rwlock_unlock(lock)         ({ printf ("unlocking %lx\n", (unsigned long) &lock); fflush(NULL); RWLOCK_CALL (unlock (&lock)); })
 # define once(once_control, init_routine)  \
   ONCE_CALL (once (&once_control, init_routine))
 #else
index a6b04f4fcbf2d23676626389691e5a51fad545f7..c952c113a3f276b4e46499240a96c8787615bea4 100644 (file)
 #include <config.h>
 #endif
 
-#include <stdlib.h>
 #include "eu-search.h"
 
-rwlock_define(static, search_find_lock);
+#include <stdio.h>
 
-void *eu_tsearch(const void *key, void **rootp,
-                int (*compar)(const void *, const void *))
+void *eu_tsearch (const void *key, search_tree *tree,
+                 int (*compare)(const void *, const void *))
 {
-  void *ret = NULL;
-  rwlock_wrlock(search_find_lock);
+  rwlock_wrlock (tree->lock);
+  void *ret = tsearch (key, &tree->root, compare);
+  rwlock_unlock (tree->lock);
 
-  ret = tsearch(key, rootp, compar);
-
-  rwlock_unlock(search_find_lock);
   return ret;
 }
 
-void *eu_tfind(const void *key, void *const *rootp,
-              int (*compar)(const void *, const void *))
+void *eu_tfind (const void *key, search_tree *tree,
+               int (*compare)(const void *, const void *))
 {
-  void *ret = NULL;
-  rwlock_rdlock(search_find_lock);
+  rwlock_rdlock (tree->lock);
+  void *ret = tfind (key, &tree->root, compare);
+  rwlock_unlock (tree->lock);
+
+  return ret;
+}
 
-  ret = tfind(key, rootp, compar);
+void *eu_tdelete (const void *key, search_tree *tree,
+                 int (*compare)(const void *, const void *))
+{
+  rwlock_wrlock (tree->lock);
+  void *ret = tdelete (key, &tree->root, compare);
+  rwlock_unlock (tree->lock);
 
-  rwlock_unlock(search_find_lock);
   return ret;
 }
+
+void eu_tdestroy (search_tree *tree, void (*free_node)(void *))
+{
+  rwlock_wrlock (tree->lock);
+
+  tdestroy (tree->root, free_node);
+  tree->root = NULL;
+
+  rwlock_unlock (tree->lock);
+}
+
+void eu_search_tree_init (search_tree *tree)
+{
+  tree->root = NULL;
+  rwlock_init (tree->lock);
+}
+
+void eu_search_tree_fini (search_tree *tree, void (*free_node)(void *))
+{
+  eu_tdestroy (tree, free_node);
+  rwlock_fini (tree->lock);
+}
index 4ce0139aa4d82c136e2f8e45933660ba6cb052ab..2dab636486f434a2cd435d7bce4c59eca9af1596 100644 (file)
 #ifndef EU_SEARCH_H
 #define EU_SEARCH_H 1
 
+#include <stdlib.h>
 #include <search.h>
+#include <eu-config.h>
 
-extern void *eu_tsearch(const void *key, void **rootp,
-                       int (*compar)(const void *, const void *));
-extern void *eu_tfind(const void *key, void *const *rootp,
-                     int (*compar)(const void *, const void *));
+typedef struct
+{
+  void *root;
+  rwlock_define (, lock);
+} search_tree;
+
+/* Search TREE for KEY and add KEY if not found. Synchronized using
+   TREE's lock.  */
+extern void *eu_tsearch (const void *key, search_tree *tree,
+                        int (*compare)(const void *, const void *));
+
+/* Search TREE for KEY. Synchronized with TREE's lock.  */
+extern void *eu_tfind (const void *key, search_tree *tree,
+                      int (*compare)(const void *, const void *));
+
+/* Delete key from TREE. Synchronized with TREE's lock.  */
+extern void *eu_tdelete (const void *key, search_tree *tree,
+                        int (*compare)(const void *, const void *));
+
+/* Free all nodes from TREE.  */
+void eu_tdestroy (search_tree *tree, void (*free_node)(void *));
+
+/* Initialize TREE's root and lock.  */
+void eu_search_tree_init (search_tree *tree);
+
+/* Free all nodes from TREE as well as TREE's lock.  */
+void eu_search_tree_fini (search_tree *tree, void (*free_node)(void *));
 
 #endif
index 3d7cb89e2a733efcba7cd68890588ef1ebbc8fd7..29c912a555be1b92b4e7ddcb41bb03a9da9fa911 100644 (file)
@@ -269,12 +269,12 @@ mask:               kMASK kBITFIELD kNUMBER
                      struct synonym *newp = xmalloc (sizeof (*newp));
                      newp->from = $2;
                      newp->to = $3;
-                     if (eu_tfind (newp, &synonyms, compare_syn) != NULL)
+                     if (tfind (newp, &synonyms, compare_syn) != NULL)
                        error (0, 0,
                               "%d: duplicate definition for synonym '%s'",
                               i386_lineno, $2);
-                     else if (eu_tsearch ( newp, &synonyms, compare_syn) == NULL)
-                       error (EXIT_FAILURE, 0, "eu_tsearch");
+                     else if (tsearch ( newp, &synonyms, compare_syn) == NULL)
+                       error (EXIT_FAILURE, 0, "tsearch");
                    }
                |
                ;
@@ -308,12 +308,12 @@ instr:              bytes ':' bitfieldopt kID bitfieldopt optargs
                          newp->bytes = $1;
                          newp->mnemonic = $4;
                          if (newp->mnemonic != (void *) -1l
-                             && eu_tfind ($4, &mnemonics,
+                             && tfind ($4, &mnemonics,
                                        (int (*)(const void *, const void *)) strcmp) == NULL)
                            {
-                             if (eu_tsearch ($4, &mnemonics,
+                             if (tsearch ($4, &mnemonics,
                                           (int (*)(const void *, const void *)) strcmp) == NULL)
-                               error (EXIT_FAILURE, errno, "eu_tsearch");
+                               error (EXIT_FAILURE, errno, "tsearch");
                              ++nmnemonics;
                            }
 
@@ -339,15 +339,15 @@ instr:              bytes ':' bitfieldopt kID bitfieldopt optargs
                                       infname, i386_lineno - 1, $5->name);
 
                              struct suffix search = { .name = $5->name };
-                             if (eu_tfind (&search, &suffixes, compare_suf)
+                             if (tfind (&search, &suffixes, compare_suf)
                                  == NULL)
                                {
                                  struct suffix *ns = xmalloc (sizeof (*ns));
                                  ns->name = $5->name;
                                  ns->idx = ++nsuffixes;
-                                 if (eu_tsearch (ns, &suffixes, compare_suf)
+                                 if (tsearch (ns, &suffixes, compare_suf)
                                      == NULL)
-                                   error (EXIT_FAILURE, errno, "eu_tsearch");
+                                   error (EXIT_FAILURE, errno, "tsearch");
                                }
                            }
 
@@ -374,7 +374,7 @@ bitfieldopt:          kBITFIELD
                      struct known_bitfield search;
                      search.name = $1;
                      struct known_bitfield **res;
-                     res = eu_tfind (&search, &bitfields, bitfield_compare);
+                     res = tfind (&search, &bitfields, bitfield_compare);
                      if (res == NULL)
                        {
                          error (0, 0, "%d: unknown bitfield '%s'",
@@ -437,7 +437,7 @@ bit:                  '0'
                      struct known_bitfield search;
                      search.name = $1;
                      struct known_bitfield **res;
-                     res = eu_tfind (&search, &bitfields, bitfield_compare);
+                     res = tfind (&search, &bitfields, bitfield_compare);
                      if (res == NULL)
                        {
                          error (0, 0, "%d: unknown bitfield '%s'",
@@ -497,7 +497,7 @@ argcomp:      kBITFIELD
                      struct known_bitfield search;
                      search.name = $1;
                      struct known_bitfield **res;
-                     res = eu_tfind (&search, &bitfields, bitfield_compare);
+                     res = tfind (&search, &bitfields, bitfield_compare);
                      if (res == NULL)
                        {
                          if (strcmp ($1, "ax") == 0)
@@ -575,7 +575,7 @@ new_bitfield (char *name, unsigned long int num)
   newp->bits = num;
   newp->tmp = 0;
 
-  if (eu_tfind (newp, &bitfields, bitfield_compare) != NULL)
+  if (tfind (newp, &bitfields, bitfield_compare) != NULL)
     {
       error (0, 0, "%d: duplicated definition of bitfield '%s'",
             i386_lineno, name);
@@ -584,7 +584,7 @@ new_bitfield (char *name, unsigned long int num)
       return;
     }
 
-  if (eu_tsearch (newp, &bitfields, bitfield_compare) == NULL)
+  if (tsearch (newp, &bitfields, bitfield_compare) == NULL)
     error (EXIT_FAILURE, errno, "%d: cannot insert new bitfield '%s'",
           i386_lineno, name);
 }
@@ -813,7 +813,7 @@ fillin_arg (struct bitvalue *bytes, struct argname *name,
 
              struct synonym search = { .from = fieldname };
 
-             struct synonym **res = eu_tfind (&search, &synonyms, compare_syn);
+             struct synonym **res = tfind (&search, &synonyms, compare_syn);
              if (res != NULL)
                fieldname = (*res)->to;
 
@@ -914,26 +914,26 @@ find_numbers (void)
        if (runp->operands[i].fct != NULL)
          {
            struct argstring search = { .str = runp->operands[i].fct };
-           if (eu_tfind (&search, &fct_names[i], compare_argstring) == NULL)
+           if (tfind (&search, &fct_names[i], compare_argstring) == NULL)
              {
                struct argstring *newp = xmalloc (sizeof (*newp));
                newp->str = runp->operands[i].fct;
                newp->idx = 0;
-               if (eu_tsearch (newp, &fct_names[i], compare_argstring) == NULL)
-                 error (EXIT_FAILURE, errno, "eu_tsearch");
+               if (tsearch (newp, &fct_names[i], compare_argstring) == NULL)
+                 error (EXIT_FAILURE, errno, "tsearch");
                ++nfct_names[i];
              }
 
            if (runp->operands[i].str != NULL)
              {
                search.str = runp->operands[i].str;
-               if (eu_tfind (&search, &strs[i], compare_argstring) == NULL)
+               if (tfind (&search, &strs[i], compare_argstring) == NULL)
                  {
                    struct argstring *newp = xmalloc (sizeof (*newp));
                    newp->str = runp->operands[i].str;
                    newp->idx = 0;
-                   if (eu_tsearch (newp, &strs[i], compare_argstring) == NULL)
-                     error (EXIT_FAILURE, errno, "eu_tsearch");
+                   if (tsearch (newp, &strs[i], compare_argstring) == NULL)
+                     error (EXIT_FAILURE, errno, "tsearch");
                    ++nstrs[i];
                  }
              }
@@ -1206,7 +1206,7 @@ instrtable_out (void)
          if (instr->operands[i].fct != NULL)
            {
              struct argstring search = { .str = instr->operands[i].fct };
-             struct argstring **res = eu_tfind (&search, &fct_names[i],
+             struct argstring **res = tfind (&search, &fct_names[i],
                                              compare_argstring);
              assert (res != NULL);
              idx = (*res)->idx;
@@ -1217,7 +1217,7 @@ instrtable_out (void)
          if (instr->operands[i].str != NULL)
            {
              struct argstring search = { .str = instr->operands[i].str };
-             struct argstring **res = eu_tfind (&search, &strs[i],
+             struct argstring **res = tfind (&search, &strs[i],
                                              compare_argstring);
              assert (res != NULL);
              idx = (*res)->idx;
index 1b0d712f8b3742039ef70f1f71c090ff513ee994..bb9dc0df31f6b14b8074a72e1fe694c28a5f594f 100644 (file)
@@ -90,13 +90,13 @@ struct Dwarf_CFI_s
   Dwarf_Off next_offset;
 
   /* Search tree for the CIEs, indexed by CIE_pointer (section offset).  */
-  void *cie_tree;
+  search_tree cie_tree;
 
   /* Search tree for the FDEs, indexed by PC address.  */
-  void *fde_tree;
+  search_tree fde_tree;
 
   /* Search tree for parsed DWARF expressions, indexed by raw pointer.  */
-  void *expr_tree;
+  search_tree expr_tree;
 
   /* Backend hook.  */
   struct ebl *ebl;
index 758daef5c18d50527c237126fa538ea8bdb9a284..3d56b0578ff9558ae6198f56329801d9c2bb2197 100644 (file)
@@ -160,7 +160,8 @@ internal_function
 __libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset)
 {
   const struct dwarf_cie cie_key = { .offset = offset };
-  struct dwarf_cie **found = eu_tfind (&cie_key, &cache->cie_tree, &compare_cie);
+  struct dwarf_cie **found = eu_tfind (&cie_key, &cache->cie_tree,
+                                      &compare_cie);
   if (found != NULL)
     return *found;
 
@@ -189,7 +190,8 @@ internal_function
 __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info)
 {
   const struct dwarf_cie cie_key = { .offset = offset };
-  struct dwarf_cie **found = eu_tfind (&cie_key, &cache->cie_tree, &compare_cie);
+  struct dwarf_cie **found = eu_tfind (&cie_key, &cache->cie_tree,
+                                      &compare_cie);
   if (found == NULL)
     /* We have not read this CIE yet.  Enter it.  */
     (void) intern_new_cie (cache, offset, info);
index ca2b7e2ac44cb6ea4e7377a4cf6b141bf5f0e85f..8b806c9091ddb58bad6fb7a8bd1f4a93151f7bff 100644 (file)
@@ -354,11 +354,11 @@ valid_p (Dwarf *result)
          result->fake_loc_cu->endp
            = (result->sectiondata[IDX_debug_loc]->d_buf
               + result->sectiondata[IDX_debug_loc]->d_size);
-         result->fake_loc_cu->locs = NULL;
          result->fake_loc_cu->address_size = elf_addr_size;
          result->fake_loc_cu->offset_size = 4;
          result->fake_loc_cu->version = 4;
          result->fake_loc_cu->split = NULL;
+         result->fake_loc_cu->locs_tree.root = NULL;
        }
     }
 
@@ -382,11 +382,11 @@ valid_p (Dwarf *result)
          result->fake_loclists_cu->endp
            = (result->sectiondata[IDX_debug_loclists]->d_buf
               + result->sectiondata[IDX_debug_loclists]->d_size);
-         result->fake_loclists_cu->locs = NULL;
          result->fake_loclists_cu->address_size = elf_addr_size;
          result->fake_loclists_cu->offset_size = 4;
          result->fake_loclists_cu->version = 5;
          result->fake_loclists_cu->split = NULL;
+         result->fake_loclists_cu->locs_tree.root = NULL;
        }
     }
 
@@ -415,11 +415,11 @@ valid_p (Dwarf *result)
          result->fake_addr_cu->endp
            = (result->sectiondata[IDX_debug_addr]->d_buf
               + result->sectiondata[IDX_debug_addr]->d_size);
-         result->fake_addr_cu->locs = NULL;
          result->fake_addr_cu->address_size = elf_addr_size;
          result->fake_addr_cu->offset_size = 4;
          result->fake_addr_cu->version = 5;
          result->fake_addr_cu->split = NULL;
+         result->fake_addr_cu->locs_tree.root = NULL;
        }
     }
 
@@ -579,6 +579,7 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
       __libdw_seterrno (DWARF_E_NOMEM); /* no memory.  */
       return NULL;
     }
+  rwlock_init(result->dwarf_lock);
   result->mem_stacks = 0;
   result->mem_tails = NULL;
 
index ed8d27beadd0280de858a8a0a23820de0a11d588..cd9d04577fd3941c5e836bfc936cbe4efb4c2780 100644 (file)
@@ -62,13 +62,12 @@ cu_free (void *arg)
 {
   struct Dwarf_CU *p = (struct Dwarf_CU *) arg;
 
-  tdestroy (p->locs, noop_free);
-
   /* Only free the CU internals if its not a fake CU.  */
-  if(p != p->dbg->fake_loc_cu && p != p->dbg->fake_loclists_cu
+  if (p != p->dbg->fake_loc_cu && p != p->dbg->fake_loclists_cu
      && p != p->dbg->fake_addr_cu)
     {
       Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
+      eu_search_tree_fini (&p->locs_tree, noop_free);
 
       /* Free split dwarf one way (from skeleton to split).  */
       if (p->unit_type == DW_UT_skeleton
@@ -102,17 +101,17 @@ dwarf_end (Dwarf *dwarf)
       /* The search tree for the CUs.  NB: the CU data itself is
         allocated separately, but the abbreviation hash tables need
         to be handled.  */
-      tdestroy (dwarf->cu_tree, cu_free);
-      tdestroy (dwarf->tu_tree, cu_free);
+      eu_search_tree_fini (&dwarf->cu_tree, cu_free);
+      eu_search_tree_fini (&dwarf->tu_tree, cu_free);
 
       /* Search tree for macro opcode tables.  */
-      tdestroy (dwarf->macro_ops, noop_free);
+      eu_search_tree_fini (&dwarf->macro_ops_tree, noop_free);
 
       /* Search tree for decoded .debug_lines units.  */
-      tdestroy (dwarf->files_lines, noop_free);
+      eu_search_tree_fini (&dwarf->files_lines_tree, noop_free);
 
       /* And the split Dwarf.  */
-      tdestroy (dwarf->split_tree, noop_free);
+      eu_search_tree_fini (&dwarf->split_tree, noop_free);
 
       /* Free the internally allocated memory.  */
       for (size_t i = 0; i < dwarf->mem_stacks; i++)
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 e3894c8c509d861bc9ce6f6a999631152197aee9..c4169df6b29bd53793f4ab458cbc210d6245c67f 100644 (file)
 #include <sys/types.h>
 #include <sys/stat.h>
 
-/* find_debug_altlink() modifies "dbg->alt_dwarf".
-   dwarf_getalt() reads "main->alt_dwarf".
-   Mutual exclusion is enforced to prevent a race. */
-rwlock_define(static, alt_dwarf_lock);
 
 char *
 internal_function
@@ -156,9 +152,7 @@ find_debug_altlink (Dwarf *dbg)
       Dwarf *alt = dwarf_begin (fd, O_RDONLY);
       if (alt != NULL)
        {
-         rwlock_wrlock(alt_dwarf_lock);
          dbg->alt_dwarf = alt;
-         rwlock_unlock(alt_dwarf_lock);
          dbg->alt_fd = fd;
        }
       else
@@ -166,36 +160,39 @@ find_debug_altlink (Dwarf *dbg)
     }
 }
 
+/* find_debug_altlink() modifies "dbg->alt_dwarf".
+   dwarf_getalt() reads "main->alt_dwarf".
+   Mutual exclusion is enforced to prevent a race. */
+
 Dwarf *
 dwarf_getalt (Dwarf *main)
 {
-  rwlock_rdlock(alt_dwarf_lock);
-  Dwarf *alt_dwarf_local = main->alt_dwarf;
-  rwlock_unlock(alt_dwarf_lock);
+  rwlock_rdlock(main->dwarf_lock);
 
   /* Only try once.  */
-  if (main == NULL || alt_dwarf_local == (void *) -1)
-    return NULL;
+  if (main == NULL || main->alt_dwarf == (void *) -1)
+    {
+      rwlock_unlock (main->dwarf_lock);
+      return NULL;
+    }
 
-  if (alt_dwarf_local != NULL)
-    return alt_dwarf_local;
+  if (main->alt_dwarf != NULL)
+    {
+      rwlock_unlock (main->dwarf_lock);
+      return main->alt_dwarf;
+    }
 
   find_debug_altlink (main);
 
-  rwlock_rdlock(alt_dwarf_lock);
-  alt_dwarf_local = main->alt_dwarf;
-  rwlock_unlock(alt_dwarf_lock);
-
   /* If we found nothing, make sure we don't try again.  */
-  if (alt_dwarf_local == NULL)
+  if (main->alt_dwarf == NULL)
     {
-      rwlock_wrlock(alt_dwarf_lock);
       main->alt_dwarf = (void *) -1;
-      rwlock_unlock(alt_dwarf_lock);
-
+      rwlock_unlock (main->dwarf_lock);
       return NULL;
     }
 
-  return alt_dwarf_local;
+  rwlock_unlock (main->dwarf_lock);
+  return main->alt_dwarf;
 }
 INTDEF (dwarf_getalt)
index afa8a4607cf69e228323b05e4c2bf0b942ff61f1..a44971520442542ee2257e34ac8e915884073b07 100644 (file)
@@ -66,7 +66,10 @@ dwarf_getcfi (Dwarf *dbg)
       cfi->default_same_value = false;
 
       cfi->next_offset = 0;
-      cfi->cie_tree = cfi->fde_tree = cfi->expr_tree = NULL;
+
+      eu_search_tree_init (&cfi->cie_tree);
+      eu_search_tree_init (&cfi->fde_tree);
+      eu_search_tree_init (&cfi->expr_tree);
 
       cfi->ebl = NULL;
 
index 35b1e626d65d36434b38197ee5be1473461774c5..a6615aadfc655598aa7d92e8c8b42286452cb841 100644 (file)
@@ -34,7 +34,7 @@
 #include <eu-search.h>
 #include <stdlib.h>
 #include <assert.h>
-
+#include <cfi.h>
 #include <libdwP.h>
 
 
@@ -139,7 +139,7 @@ loc_compare (const void *p1, const void *p2)
    This points us directly to the block data for later fetching.
    Returns zero on success, -1 on bad DWARF or 1 if eu_tsearch failed.  */
 static int
-store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op)
+store_implicit_value (Dwarf *dbg, search_tree *cache, Dwarf_Op *op)
 {
   if (dbg == NULL)
     return -1;
@@ -167,7 +167,8 @@ dwarf_getlocation_implicit_value (Dwarf_Attribute *attr, const Dwarf_Op *op,
     return -1;
 
   struct loc_block_s fake = { .addr = (void *) op };
-  struct loc_block_s **found = eu_tfind (&fake, &attr->cu->locs, loc_compare);
+  struct loc_block_s **found = eu_tfind (&fake, &attr->cu->locs_tree,
+                                        loc_compare);
   if (unlikely (found == NULL))
     {
       __libdw_seterrno (DWARF_E_NO_BLOCK);
@@ -211,7 +212,7 @@ is_constant_offset (Dwarf_Attribute *attr,
 
   /* Check whether we already cached this location.  */
   struct loc_s fake = { .addr = attr->valp };
-  struct loc_s **found = eu_tfind (&fake, &attr->cu->locs, loc_compare);
+  struct loc_s **found = eu_tfind (&fake, &attr->cu->locs_tree, loc_compare);
 
   if (found == NULL)
     {
@@ -235,7 +236,7 @@ is_constant_offset (Dwarf_Attribute *attr,
       newp->loc = result;
       newp->nloc = 1;
 
-      found = eu_tsearch (newp, &attr->cu->locs, loc_compare);
+      found = eu_tsearch (newp, &attr->cu->locs_tree, loc_compare);
     }
 
   assert ((*found)->nloc == 1);
@@ -253,7 +254,7 @@ int
 internal_function
 __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
                           unsigned int address_size, unsigned int ref_size,
-                          void **cache, const Dwarf_Block *block,
+                          search_tree *cache, const Dwarf_Block *block,
                           bool cfap, bool valuep,
                           Dwarf_Op **llbuf, size_t *listlen, int sec_index)
 {
@@ -655,7 +656,7 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
   newp->addr = block->data;
   newp->loc = result;
   newp->nloc = *listlen;
-  (void) eu_tsearch (newp, cache, loc_compare);
+  eu_tsearch (newp, cache, loc_compare);
 
   /* We did it.  */
   return 0;
@@ -677,7 +678,7 @@ getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
                                    cu->address_size, (cu->version == 2
                                                       ? cu->address_size
                                                       : cu->offset_size),
-                                   &cu->locs, block,
+                                   &cu->locs_tree, block,
                                    false, false,
                                    llbuf, listlen, sec_index);
 }
index 0118c7699f2bcdff96f523a8b8f4588d03b0cbaf..41d510a9df825100c6fcca622edec45d110fd53c 100644 (file)
@@ -317,7 +317,7 @@ cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff,
                Dwarf_Die *cudie)
 {
   Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index };
-  Dwarf_Macro_Op_Table **found = eu_tfind (&fake, &dbg->macro_ops,
+  Dwarf_Macro_Op_Table **found = eu_tfind (&fake, &dbg->macro_ops_tree,
                                        macro_op_compare);
   if (found != NULL)
     return *found;
@@ -329,7 +329,7 @@ cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff,
   if (table == NULL)
     return NULL;
 
-  Dwarf_Macro_Op_Table **ret = eu_tsearch (table, &dbg->macro_ops,
+  Dwarf_Macro_Op_Table **ret = eu_tsearch (table, &dbg->macro_ops_tree,
                                        macro_op_compare);
   if (unlikely (ret == NULL))
     {
index bc717e53f8efdfdc911730e32792349bb339f62d..759b9c7ba462c7154eb85f20973b611bddc1ff3d 100644 (file)
@@ -1320,7 +1320,7 @@ get_lines_or_files (Dwarf *dbg, Dwarf_Off debug_line_offset,
                    Dwarf_Lines **linesp, Dwarf_Files **filesp)
 {
   struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
-  struct files_lines_s **found = eu_tfind (&fake, &dbg->files_lines,
+  struct files_lines_s **found = eu_tfind (&fake, &dbg->files_lines_tree,
                                           files_lines_compare);
   if (found == NULL)
     {
@@ -1354,7 +1354,7 @@ get_lines_or_files (Dwarf *dbg, Dwarf_Off debug_line_offset,
 
       node->debug_line_offset = debug_line_offset;
 
-      found = eu_tsearch (node, &dbg->files_lines, files_lines_compare);
+      found = eu_tsearch (node, &dbg->files_lines_tree, files_lines_compare);
       if (found == NULL)
        {
          __libdw_seterrno (DWARF_E_NOMEM);
index 92f8de685f1b811ba9bca54ff453adf99671c258..d5dde5912af3538de4aa50b1cd5c57f07fb50d55 100644 (file)
@@ -37,7 +37,6 @@
 /* dwarf_hasattr() calls __libdw_dieabbrev() in libdwP.h.
    __libdw_dieabbrev() reads/writes "die->abbrev".
    Mutual exclusion is enforced around the call to __libdw_dieabbrev to prevent a race. */
-rwlock_define(static, die_abbrev_lock);
 
 int
 dwarf_hasattr (Dwarf_Die *die, unsigned int search_name)
@@ -45,12 +44,12 @@ dwarf_hasattr (Dwarf_Die *die, unsigned int search_name)
   if (die == NULL)
     return 0;
 
-  rwlock_wrlock(die_abbrev_lock);
+  //rwlock_wrlock(die_abbrev_lock);
 
   /* Find the abbreviation entry.  */
   Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
 
-  rwlock_unlock(die_abbrev_lock);
+  //rwlock_unlock(die_abbrev_lock);
 
   if (unlikely (abbrevp == DWARF_END_ABBREV))
     {
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 55065528aa71e46725acdc9b4aee090922fbf2d3..5dc4ad026b8975c1244157a140a871be391ee371 100644 (file)
@@ -123,6 +123,7 @@ intern_fde (Dwarf_CFI *cache, const Dwarf_FDE *entry)
 
   /* Add the new entry to the search tree.  */
   struct dwarf_fde **tres = eu_tsearch (fde, &cache->fde_tree, &compare_fde);
+
   if (tres == NULL)
     {
       free (fde);
index 683f7f17ae9f881d7d21ac1a8507c826bd75b5bb..6c89858a3b37800c64b4677ab26c9f38342fdb07 100644 (file)
@@ -60,10 +60,10 @@ void
 internal_function
 __libdw_destroy_frame_cache (Dwarf_CFI *cache)
 {
-  /* Most of the data is in our two search trees.  */
-  tdestroy (cache->fde_tree, free_fde);
-  tdestroy (cache->cie_tree, free_cie);
-  tdestroy (cache->expr_tree, free_expr);
+  /* Most of the data is in our three search trees.  */
+  eu_search_tree_fini (&cache->fde_tree, free_fde);
+  eu_search_tree_fini (&cache->cie_tree, free_cie);
+  eu_search_tree_fini (&cache->expr_tree, free_expr);
 
   if (cache->ebl != NULL && cache->ebl != (void *) -1l)
     ebl_closebackend (cache->ebl);
index d53dc7871dc9029708587738e8f298077635fa9b..54dfc9c100680d2a91597cfe372276b6f29a5898 100644 (file)
@@ -125,7 +125,8 @@ typedef struct
   /* The offset can be computed from the address.  */
   void *addr;
   struct Dwarf_CU *cu;
-  Dwarf_Abbrev *abbrev;
+  //_Atomic Dwarf_Abbrev * abbrev;
+  Dwarf_Abbrev * abbrev;
   // XXX We'll see what other information will be needed.
   long int padding__;
 } Dwarf_Die;
index e55ff50ac64a3de444fbb28c4850e78ce9c49265..a84ba7f5c91c332d02e271128e99514e086d289d 100644 (file)
@@ -32,6 +32,7 @@
 #include <stdbool.h>
 #include <pthread.h>
 
+#include <eu-search.h>
 #include <libdw.h>
 #include <dwarf.h>
 
@@ -215,22 +216,22 @@ struct Dwarf
   size_t pubnames_nsets;
 
   /* Search tree for the CUs.  */
-  void *cu_tree;
+  search_tree cu_tree;
   Dwarf_Off next_cu_offset;
 
   /* Search tree and sig8 hash table for .debug_types type units.  */
-  void *tu_tree;
+  search_tree tu_tree;
   Dwarf_Off next_tu_offset;
   Dwarf_Sig8_Hash sig8_hash;
 
   /* Search tree for split Dwarf associated with CUs in this debug.  */
-  void *split_tree;
+  search_tree split_tree;
 
   /* Search tree for .debug_macro operator tables.  */
-  void *macro_ops;
+  search_tree macro_ops_tree;
 
   /* Search tree for decoded .debug_line units.  */
-  void *files_lines;
+  search_tree files_lines_tree;
 
   /* Address ranges read from .debug_aranges.  */
   Dwarf_Aranges *aranges;
@@ -263,6 +264,12 @@ struct Dwarf
      allocations for this Dwarf.  */
   pthread_rwlock_t mem_rwl;
 
+  /* The dwarf_lock is a read-write lock designed to ensure thread-safe access and modification 
+    of Dwarf objects. It guards against concurrent access issues by allowing multiple threads 
+    to read or a single thread to write, thereby preventing data races and ensuring consistency 
+    in multithreaded environments.  */
+  rwlock_define(, dwarf_lock);
+
   /* Internal memory handling.  This is basically a simplified thread-local
      reimplementation of obstacks.  Unfortunately the standard obstack
      implementation is not usable in libraries.  */
@@ -423,7 +430,7 @@ struct Dwarf_CU
   Dwarf_Files *files;
 
   /* Known location lists.  */
-  void *locs;
+  search_tree locs_tree;
 
   /* Base address for use with ranges and locs.
      Don't access directly, call __libdw_cu_base_address.  */
@@ -799,9 +806,14 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
       /* 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;
+       {
+         die->abbrev = DWARF_END_ABBREV;
+         return DWARF_END_ABBREV;
+       }
+
       get_uleb128 (code, addr, die->cu->endp);
       if (readp != NULL)
        *readp = addr;
@@ -810,7 +822,7 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
       if (die->abbrev == NULL)
        die->abbrev = __libdw_findabbrev (die->cu, code);
     }
-  return die->abbrev;
+  return (Dwarf_Abbrev *) die->abbrev;
 }
 
 /* Helper functions for form handling.  */
@@ -912,7 +924,8 @@ extern int __libdw_intern_expression (Dwarf *dbg,
                                      bool other_byte_order,
                                      unsigned int address_size,
                                      unsigned int ref_size,
-                                     void **cache, const Dwarf_Block *block,
+                                     search_tree *cache,
+                                     const Dwarf_Block *block,
                                      bool cfap, bool valuep,
                                      Dwarf_Op **llbuf, size_t *listlen,
                                      int sec_index)
index a17eac5063bdfe279c3d3bc4f5e47b227b4ccdc1..323579cc010ea5f9dfca7542e6a3d4e4fc50ca0f 100644 (file)
@@ -64,20 +64,16 @@ try_split_file (Dwarf_CU *cu, const char *dwo_path)
                  && cu->unit_id8 == split->unit_id8)
                {
                  if (eu_tsearch (split->dbg, &cu->dbg->split_tree,
-                              __libdw_finddbg_cb) == NULL)
+                                 __libdw_finddbg_cb) == NULL)
                    {
                      /* Something went wrong.  Don't link.  */
                      __libdw_seterrno (DWARF_E_NOMEM);
                      break;
                    }
 
-                 rwlock_wrlock(cu_split_lock);
-
                  /* Link skeleton and split compile units.  */
                  __libdw_link_skel_split (cu, split);
 
-                 rwlock_unlock(cu_split_lock);
-
                  /* We have everything we need from this ELF
                     file.  And we are going to close the fd to
                     not run out of file descriptors.  */
@@ -86,12 +82,8 @@ try_split_file (Dwarf_CU *cu, const char *dwo_path)
                }
            }
 
-         rwlock_rdlock(cu_split_lock);
-
          if (cu->split == (Dwarf_CU *) -1)
            dwarf_end (split_dwarf);
-
-         rwlock_unlock(cu_split_lock);
        }
       /* Always close, because we don't want to run out of file
         descriptors.  See also the elf_fcntl ELF_C_FDDONE call
@@ -147,8 +139,8 @@ try_dwp_file (Dwarf_CU *cu)
                                               cu->unit_id8);
       if (split != NULL)
        {
-         if (tsearch (split->dbg, &cu->dbg->split_tree,
-                      __libdw_finddbg_cb) == NULL)
+         if (eu_tsearch (split->dbg, &cu->dbg->split_tree,
+                         __libdw_finddbg_cb) == NULL)
            {
              /* Something went wrong.  Don't link.  */
              __libdw_seterrno (DWARF_E_NOMEM);
@@ -165,13 +157,14 @@ Dwarf_CU *
 internal_function
 __libdw_find_split_unit (Dwarf_CU *cu)
 {
-  rwlock_rdlock(cu_split_lock);
-  Dwarf_CU *cu_split_local = cu->split;
   rwlock_unlock(cu_split_lock);
 
   /* Only try once.  */
-  if (cu_split_local != (Dwarf_CU *) -1)
-    return cu_split_local;
+  if (cu->split != (Dwarf_CU *) -1)
+    {
+      rwlock_unlock(cu_split_lock);
+      return cu->split;
+    }
 
   /* 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
@@ -200,11 +193,7 @@ __libdw_find_split_unit (Dwarf_CU *cu)
              free (dwo_path);
            }
 
-         rwlock_rdlock(cu_split_lock);
-         cu_split_local = cu->split;
-         rwlock_unlock(cu_split_lock);
-
-         if (cu_split_local == (Dwarf_CU *) -1)
+         if (cu->split == (Dwarf_CU *) -1)
            {
              /* Try compdir plus dwo_name.  */
              Dwarf_Attribute compdir;
@@ -230,11 +219,8 @@ __libdw_find_split_unit (Dwarf_CU *cu)
 
   /* If we found nothing, make sure we don't try again.  */
   if (cu->split == (Dwarf_CU *) -1)
-    {
       cu->split = NULL;
-      cu_split_local = cu->split;
-    }
 
   rwlock_unlock(cu_split_lock);
-  return cu_split_local;
+  return cu->split;
 }
index c9c433e78b9a8802fe31cc6766f12461c64c7836..93ed2570ab7ffca83955db1630c298cf7c62d3a0 100644 (file)
@@ -37,7 +37,7 @@
 
 /* __libdw_findcu modifies "&dbg->next_tu_offset : &dbg->next_cu_offset".
    May read or write, so mutual exclusion is enforced to prevent a race. */
-rwlock_define(static, next_tucu_offset_lock);
+//rwlock_define(static, next_tucu_offset_lock);
 
 static int
 findcu_cb (const void *arg1, const void *arg2)
@@ -105,7 +105,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
 {
   Dwarf_Off *const offsetp
     = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
-  void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree;
+  search_tree *tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree;
 
   Dwarf_Off oldoff = *offsetp;
   uint16_t version;
@@ -171,7 +171,8 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
   newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset;
   newp->files = NULL;
   newp->lines = NULL;
-  newp->locs = NULL;
+  newp->locs_tree.root = NULL;
+  rwlock_init (newp->locs_tree.lock);
   newp->split = (Dwarf_CU *) -1;
   newp->base_address = (Dwarf_Addr) -1;
   newp->addr_base = (Dwarf_Off) -1;
@@ -240,7 +241,7 @@ struct Dwarf_CU *
 internal_function
 __libdw_findcu (Dwarf *dbg, Dwarf_Off start, bool v4_debug_types)
 {
-  void **tree = v4_debug_types ? &dbg->tu_tree : &dbg->cu_tree;
+  search_tree *tree = v4_debug_types ? &dbg->tu_tree : &dbg->cu_tree;
   Dwarf_Off *next_offset
     = v4_debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
 
@@ -252,7 +253,7 @@ __libdw_findcu (Dwarf *dbg, Dwarf_Off start, bool v4_debug_types)
   if (found != NULL)
     return *found;
 
-  rwlock_wrlock(next_tucu_offset_lock);
+  rwlock_wrlock(dbg->dwarf_lock);
 
   if (start < *next_offset)
     __libdw_seterrno (DWARF_E_INVALID_DWARF);
@@ -278,7 +279,7 @@ __libdw_findcu (Dwarf *dbg, Dwarf_Off start, bool v4_debug_types)
        }
     }
 
-  rwlock_unlock(next_tucu_offset_lock);
+  rwlock_unlock(dbg->dwarf_lock);
   return result;
 }
 
@@ -286,7 +287,7 @@ struct Dwarf_CU *
 internal_function
 __libdw_findcu_addr (Dwarf *dbg, void *addr)
 {
-  void **tree;
+  search_tree *tree;
   Dwarf_Off start;
   if (addr >= dbg->sectiondata[IDX_debug_info]->d_buf
       && addr < (dbg->sectiondata[IDX_debug_info]->d_buf
index ff8b2607ac11ca13b7c9e66c118569cbb2e67ae5..d10c562af422c0acb2c1e4179b2913023f30dd40 100644 (file)
@@ -151,8 +151,7 @@ less_lazy (Dwfl_Module *mod)
     return;
 
   /* We know about all the CUs now, we don't need this table.  */
-  tdestroy (mod->lazy_cu_root, nofree);
-  mod->lazy_cu_root = NULL;
+  eu_tdestroy (&mod->lazy_cu_tree, nofree);
 }
 
 static inline Dwarf_Off
@@ -198,7 +197,8 @@ intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu **result)
 
   struct dwfl_cu key;
   key.die.cu = die->cu;
-  struct dwfl_cu **found = eu_tsearch (&key, &mod->lazy_cu_root, &compare_cukey);
+  struct dwfl_cu **found = eu_tsearch (&key, &mod->lazy_cu_tree,
+                                      &compare_cukey);
   if (unlikely (found == NULL))
     return DWFL_E_NOMEM;
 
index c4d872d497f0c4ae09085eac6fa825a42dc50bb2..b4ddf806739c2973543375a43f78758a88c43f97 100644 (file)
@@ -61,8 +61,7 @@ void
 internal_function
 __libdwfl_module_free (Dwfl_Module *mod)
 {
-  if (mod->lazy_cu_root != NULL)
-    tdestroy (mod->lazy_cu_root, nofree);
+  eu_search_tree_fini (&mod->lazy_cu_tree, nofree);
 
   if (mod->aranges != NULL)
     free (mod->aranges);
@@ -200,6 +199,7 @@ dwfl_report_module (Dwfl *dwfl, const char *name,
   mod->low_addr = start;
   mod->high_addr = end;
   mod->dwfl = dwfl;
+  eu_search_tree_init (&mod->lazy_cu_tree);
 
   return use (mod, tailp, dwfl);
 }
index b3dfea1d1b9aa4114c5ad58b01be261572221013..bfb4bf275e368151a90054b31ab097b61f6580a1 100644 (file)
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <eu-search.h>
 
 #include "libdwP.h"    /* We need its INTDECLs.  */
 #include "libdwelfP.h"
@@ -199,7 +200,7 @@ struct Dwfl_Module
   /* Known CU's in this module.  */
   struct dwfl_cu *first_cu, **cu;
 
-  void *lazy_cu_root;          /* Table indexed by Dwarf_Off of CU.  */
+  search_tree lazy_cu_tree;    /* Table indexed by Dwarf_Off of CU.  */
 
   struct dwfl_arange *aranges; /* Mapping of addresses in module to CUs.  */
 
index 9b2a856d118a55c0977bbc8d9978d8f6b42f18b3..10b53e93e462d7763f8d87121091494d6c52652d 100644 (file)
@@ -92,9 +92,9 @@ allocate_elf (int fildes, void *map_address, int64_t offset, size_t maxsize,
 /* Acquire lock for the descriptor and all children.  */
 static void
 __attribute__ ((unused))
-libelf_acquire_all (Elf *elf)
+libelf_acquire_all_children (Elf *elf)
 {
-  rwlock_wrlock (elf->lock);
+//  rwlock_wrlock (elf->lock);
 
   if (elf->kind == ELF_K_AR)
     {
@@ -103,7 +103,10 @@ libelf_acquire_all (Elf *elf)
       while (child != NULL)
        {
          if (child->ref_count != 0)
-           libelf_acquire_all (child);
+    {
+      rwlock_wrlock(child->lock);
+           libelf_acquire_all_children (child);
+    }
          child = child->next;
        }
     }
@@ -112,7 +115,7 @@ libelf_acquire_all (Elf *elf)
 /* Release own lock and those of the children.  */
 static void
 __attribute__ ((unused))
-libelf_release_all (Elf *elf)
+libelf_release_all_children (Elf *elf)
 {
   if (elf->kind == ELF_K_AR)
     {
@@ -121,12 +124,15 @@ libelf_release_all (Elf *elf)
       while (child != NULL)
        {
          if (child->ref_count != 0)
-           libelf_release_all (child);
+    {
+      rwlock_unlock (child->lock);
+           libelf_release_all_children (child);
+    }
          child = child->next;
        }
     }
 
-  rwlock_unlock (elf->lock);
+//  rwlock_unlock (elf->lock);
 }
 
 
index 8a49f35125bbba8230f0cb364e0b24545af52dac..2b3b465f63ec7da9c13b17f5243d09963f394fb3 100644 (file)
@@ -439,6 +439,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
 
       /* So far only one block with sections.  */
       elf->state.elf32.scns_last = &elf->state.elf32.scns;
+      eu_search_tree_init (&elf->state.elf32.rawchunk_tree);
     }
   else
     {
@@ -536,6 +537,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
 
       /* So far only one block with sections.  */
       elf->state.elf64.scns_last = &elf->state.elf64.scns;
+      eu_search_tree_init (&elf->state.elf64.rawchunk_tree);
     }
 
   return elf;
index 64087c7d60ddcfd0f6a00c0b629f392aa0c5618d..cf5a59d06531e6ab60b5f17dc16dcea5c92aecc2 100644 (file)
@@ -53,11 +53,9 @@ elf_cntl (Elf *elf, Elf_Cmd cmd)
   switch (cmd)
     {
     case ELF_C_FDREAD:
-     rwlock_rdlock (elf->lock);
-     int addr_isnull = elf->map_address == NULL;
-     rwlock_unlock(elf->lock);
+
       /* If not all of the file is in the memory read it now.  */
-      if (addr_isnull && __libelf_readall (elf) == NULL)
+      if (__libelf_readall (elf) == NULL)
        {
          /* We were not able to read everything.  */
          result = -1;
index 80f4d13fae8c180ea88f4eb2aae2a9398c258701..da8f3a20699235e0ea715a5443852ba9bf89153b 100644 (file)
@@ -126,13 +126,14 @@ elf_end (Elf *elf)
 
     case ELF_K_ELF:
       {
-       void *rawchunks
+       search_tree *rawchunk_tree
          = (elf->class == ELFCLASS32
-            || (offsetof (struct Elf, state.elf32.rawchunks)
-                == offsetof (struct Elf, state.elf64.rawchunks))
-            ? elf->state.elf32.rawchunks
-            : elf->state.elf64.rawchunks);
-       tdestroy (rawchunks, free_chunk);
+            || (offsetof (struct Elf, state.elf32.rawchunk_tree)
+                == offsetof (struct Elf, state.elf64.rawchunk_tree))
+            ? &elf->state.elf32.rawchunk_tree
+            : &elf->state.elf64.rawchunk_tree);
+
+       eu_search_tree_fini (rawchunk_tree, free_chunk);
 
        Elf_ScnList *list = (elf->class == ELFCLASS32
                             || (offsetof (struct Elf, state.elf32.scns)
index 1751878d6f2a86f24f98d72089f681c5afe4bb96..3269dc6c7669467e2c227a2bc31ffbbab7304af8 100644 (file)
@@ -33,8 +33,7 @@
 
 #include <assert.h>
 #include <errno.h>
-#include <search.h>
-#include <stdlib.h>
+#include <eu-search.h>
 #include <string.h>
 
 #include "libelfP.h"
@@ -95,8 +94,9 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
   key.offset = offset;
   key.data.d.d_size = size;
   key.data.d.d_type = type;
-  Elf_Data_Chunk **found = tsearch (&key, &elf->state.elf.rawchunks,
-                                   &chunk_compare);
+  Elf_Data_Chunk **found
+    = eu_tsearch (&key, &elf->state.elf.rawchunk_tree, &chunk_compare);
+
   if (found == NULL)
     goto nomem;
 
@@ -136,7 +136,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
       if (rawchunk == NULL)
        {
        nomem:
-         tdelete (&key, &elf->state.elf.rawchunks, &chunk_compare);
+         eu_tdelete (&key, &elf->state.elf.rawchunk_tree, &chunk_compare);
          __libelf_seterrno (ELF_E_NOMEM);
          goto out;
        }
@@ -147,7 +147,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
                    != size))
        {
          /* Something went wrong.  */
-         tdelete (&key, &elf->state.elf.rawchunks, &chunk_compare);
+         eu_tdelete (&key, &elf->state.elf.rawchunk_tree, &chunk_compare);
          free (rawchunk);
          __libelf_seterrno (ELF_E_READ_ERROR);
          goto out;
index 2d62d4471ccca180a813e0c655af80ea44b8f184..a804cd85e5cbbfa360c91f794aaefeaca6f1e347 100644 (file)
@@ -84,8 +84,7 @@ __libelf_readall (Elf *elf)
 
       /* If this is an archive and we have derived descriptors get the
         locks for all of them.  */
-      rwlock_unlock(elf->lock); // lock will be reacquired next line
-      libelf_acquire_all (elf);
+      libelf_acquire_all_children (elf);
 
       if (elf->maximum_size == ~((size_t) 0))
        {
@@ -117,6 +116,7 @@ __libelf_readall (Elf *elf)
            {
              /* Something went wrong.  */
            read_error:
+             rwlock_unlock (elf->lock);
              __libelf_seterrno (ELF_E_READ_ERROR);
              free (mem);
            }
@@ -142,8 +142,9 @@ __libelf_readall (Elf *elf)
        __libelf_seterrno (ELF_E_NOMEM);
 
       /* Free the locks on the children.  */
-      libelf_release_all (elf); // lock is released
+      libelf_release_all_children (elf);
     }
 
+  rwlock_unlock (elf->lock);
   return (char *) elf->map_address;
 }
index bdd2cc6ac27d7432929023cef4f822098d863a61..3e4ab2f3e3ea48160f2917575b768790a39234e0 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <ar.h>
 #include <gelf.h>
+#include <eu-search.h>
 
 #include <errno.h>
 #include <stdbool.h>
@@ -323,7 +324,8 @@ struct Elf
       Elf_ScnList *scns_last;  /* Last element in the section list.
                                   If NULL the data has not yet been
                                   read from the file.  */
-      void *rawchunks;         /* Tree of elf_getdata_rawchunk results.  */
+      search_tree rawchunk_tree;  /* Tree and lock for elf_getdata_rawchunk
+                                    results.  */
       unsigned int scnincr;    /* Number of sections allocate the last
                                   time.  */
       int ehdr_flags;          /* Flags (dirty) for ELF header.  */
@@ -342,7 +344,8 @@ struct Elf
       Elf_ScnList *scns_last;  /* Last element in the section list.
                                   If NULL the data has not yet been
                                   read from the file.  */
-      void *rawchunks;         /* Tree of elf_getdata_rawchunk results.  */
+      search_tree rawchunk_tree;  /* Tree and lock for
+                                    elf_getdata_rawchunk results.  */
       unsigned int scnincr;    /* Number of sections allocate the last
                                   time.  */
       int ehdr_flags;          /* Flags (dirty) for ELF header.  */
@@ -367,7 +370,8 @@ struct Elf
       Elf_ScnList *scns_last;  /* Last element in the section list.
                                   If NULL the data has not yet been
                                   read from the file.  */
-      void *rawchunks;         /* Tree of elf_getdata_rawchunk results.  */
+      search_tree rawchunk_tree;  /* Tree and lock for
+                                    elf_getdata_rawchunk results.  */
       unsigned int scnincr;    /* Number of sections allocate the last
                                   time.  */
       int ehdr_flags;          /* Flags (dirty) for ELF header.  */
diff --git a/tests/.Makefile.am.rej.swp b/tests/.Makefile.am.rej.swp
deleted file mode 100644 (file)
index e2cc8cc..0000000
Binary files a/tests/.Makefile.am.rej.swp and /dev/null differ