* libdw/dwarf_end.c (cu_free): Free str_off_base_lock.
* libdw/libdwP.h (struct Dwarf_CU): Add str_off_base_lock member.
(str_offsets_base_off): Add locking.
* libdw/libdw_findcu.c (__libdw_intern_next_unit): Initialize
str_off_base_lock.
Signed-off-by: Aaron Merey <[email protected]>
---
v3:
https://patchwork.sourceware.org/project/elfutils/patch/[email protected]/
v4: simplify unlocking in str_offsets_base_off.
libdw/dwarf_end.c | 1 +
libdw/libdwP.h | 17 +++++++++++++++--
libdw/libdw_findcu.c | 1 +
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index c12815e1..1628e448 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -71,6 +71,7 @@ cu_free (void *arg)
rwlock_fini (p->abbrev_lock);
rwlock_fini (p->split_lock);
mutex_fini (p->src_lock);
+ mutex_fini (p->str_off_base_lock);
/* Free split dwarf one way (from skeleton to split). */
if (p->unit_type == DW_UT_skeleton
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 974d6a50..383a26b4 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -467,6 +467,10 @@ struct Dwarf_CU
Covers dwarf_getsrclines and dwarf_getsrcfiles. */
mutex_define(, src_lock);
+ /* Synchronize access to the str_off_base of this Dwarf_CU.
+ Covers __libdw_str_offsets_base_off. */
+ mutex_define(, str_off_base_lock);
+
/* Memory boundaries of this CU. */
void *startp;
void *endp;
@@ -1208,6 +1212,7 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
Dwarf_Off off = 0;
if (cu != NULL)
{
+ mutex_lock (cu->str_off_base_lock);
if (cu->str_off_base == (Dwarf_Off) -1)
{
Dwarf_Off dwp_offset;
@@ -1222,6 +1227,7 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
if (dwarf_formudata (&attr, &base) == 0)
{
cu->str_off_base = off + base;
+ mutex_unlock (cu->str_off_base_lock);
return cu->str_off_base;
}
}
@@ -1229,6 +1235,7 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
if (cu->version < 5)
{
cu->str_off_base = off;
+ mutex_unlock (cu->str_off_base_lock);
return cu->str_off_base;
}
@@ -1236,7 +1243,10 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
dbg = cu->dbg;
}
else
- return cu->str_off_base;
+ {
+ mutex_unlock (cu->str_off_base_lock);
+ return cu->str_off_base;
+ }
}
/* No str_offsets_base attribute, we have to assume "zero".
@@ -1286,7 +1296,10 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
no_header:
if (cu != NULL)
- cu->str_off_base = off;
+ {
+ cu->str_off_base = off;
+ mutex_unlock (cu->str_off_base_lock);
+ }
return off;
}
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index f0243643..8805af9b 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -180,6 +180,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
rwlock_init (newp->abbrev_lock);
rwlock_init (newp->split_lock);
mutex_init (newp->src_lock);
+ mutex_init (newp->str_off_base_lock);
/* v4 debug type units have version == 4 and unit_type == DW_UT_type. */
if (debug_types)
--
2.48.1