summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeather McIntyre <[email protected]>2024-08-20 16:42:03 -0400
committerAaron Merey <[email protected]>2024-08-20 20:19:13 -0400
commit2630bce7476b70e2abb42da0aabaa63006b290cf (patch)
treef4af2528e8d22adf05b77289d311884139b63d64
parent28b74a1bf73b86ec461c20e17c405d8b64bdba77 (diff)
libdw: Make libdw_find_split_unit thread-safe
* 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 <[email protected]> Signed-off-by: Aaron Merey <[email protected]> Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r--libdw/dwarf_end.c1
-rw-r--r--libdw/dwarf_formref_die.c3
-rw-r--r--libdw/libdwP.h3
-rw-r--r--libdw/libdw_find_split_unit.c15
-rw-r--r--libdw/libdw_findcu.c1
5 files changed, 21 insertions, 2 deletions
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 487d6ce7..ee3ed74e 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -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
diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c
index 48ba8194..69d1bf1c 100644
--- a/libdw/dwarf_formref_die.c
+++ b/libdw/dwarf_formref_die.c
@@ -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)
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 8ba87463..d6bab606 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -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;
diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c
index 4005793b..f4f34c5d 100644
--- a/libdw/libdw_find_split_unit.c
+++ b/libdw/libdw_find_split_unit.c
@@ -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;
}
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index 0f46d777..c74e895e 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -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)