From: Heather McIntyre Date: Tue, 16 Jul 2024 16:25:57 +0000 (-0400) Subject: libdwP.h: Add locking to __libdw_dieabbrev X-Git-Tag: elfutils-0.192~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28b74a1bf73b86ec461c20e17c405d8b64bdba77;p=thirdparty%2Felfutils.git libdwP.h: Add locking to __libdw_dieabbrev * libdw/dwarf_end.c (cu_free): Free abbrev_lock. * libdw/libdwP.h (__libdw_dieabbrev): Add locking. (struct Dwarf_CU): Define abbrev_lock. * libdw/libdw_findcu.c (__libdw_intern_next_unit): Init abbrev_lock. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard --- diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c index eaa97050..487d6ce7 100644 --- a/libdw/dwarf_end.c +++ b/libdw/dwarf_end.c @@ -68,6 +68,7 @@ cu_free (void *arg) && p != p->dbg->fake_addr_cu) { Dwarf_Abbrev_Hash_free (&p->abbrev_hash); + rwlock_fini (p->abbrev_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 85b4e01a..8ba87463 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -451,6 +451,10 @@ struct Dwarf_CU Don't access directly, call __libdw_cu_locs_base. */ Dwarf_Off locs_base; + /* Synchronize access to the abbrev member of a Dwarf_Die that + refers to this Dwarf_CU. */ + rwlock_define(, abbrev_lock); + /* Memory boundaries of this CU. */ void *startp; void *endp; @@ -798,15 +802,28 @@ static inline Dwarf_Abbrev * __nonnull_attribute__ (1) __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) { + if (unlikely (die->cu == NULL)) + { + die->abbrev = DWARF_END_ABBREV; + return DWARF_END_ABBREV; + } + + rwlock_wrlock (die->cu->abbrev_lock); + /* Do we need to get the abbreviation, or need to read after the code? */ if (die->abbrev == NULL || readp != NULL) { /* 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; + + if (addr >= (const unsigned char *) die->cu->endp) + { + die->abbrev = DWARF_END_ABBREV; + rwlock_unlock (die->cu->abbrev_lock); + return DWARF_END_ABBREV; + } + get_uleb128 (code, addr, die->cu->endp); if (readp != NULL) *readp = addr; @@ -815,7 +832,11 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) if (die->abbrev == NULL) die->abbrev = __libdw_findabbrev (die->cu, code); } - return die->abbrev; + + Dwarf_Abbrev *result = die->abbrev; + rwlock_unlock (die->cu->abbrev_lock); + + return result; } /* Helper functions for form handling. */ diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index bfbad410..0f46d777 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -177,6 +177,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->startp = data->d_buf + newp->start; newp->endp = data->d_buf + newp->end; eu_search_tree_init (&newp->locs_tree); + rwlock_init (newp->abbrev_lock); /* v4 debug type units have version == 4 and unit_type == DW_UT_type. */ if (debug_types)