* 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 <ame...@redhat.com> --- v3: https://patchwork.sourceware.org/project/elfutils/patch/20250220043644.2058519-3-ame...@redhat.com/ 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