From: Aaron Merey Date: Tue, 16 Jul 2024 16:25:57 +0000 (-0400) Subject: libdwP.h: Add locking to __libdw_dieabbrev X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac0e88d8b4243dc78d8c7fbd48b2ca53a0820f93;p=thirdparty%2Felfutils.git libdwP.h: Add locking to __libdw_dieabbrev * libdw/libdwP.h (__libdw_dieabbrev): Add locking. (struct Dwarf): Add dwarf_lock. (struct Dwarf_CU): Add abbrev_lock, split_lock. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard v2 changes: This replaces patch "libdw: Add locking around __libdw_dieabbrev for dwarf_hasattr". Mark suggested that we remove lazy abbrev reading in order to simplify the locking of __libdw_dieabbrev. This is a fair bit of work so for now lets just put a write lock around all of __libdw_dieabbrev. The removal of lazy reading of abbrev will be done in a future patch. --- diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c index 48ba8194..f8a51970 100644 --- a/libdw/dwarf_formref_die.c +++ b/libdw/dwarf_formref_die.c @@ -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) diff --git a/libdw/dwarf_setalt.c b/libdw/dwarf_setalt.c index dc9b61cb..f7d70d9d 100644 --- a/libdw/dwarf_setalt.c +++ b/libdw/dwarf_setalt.c @@ -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) diff --git a/libdw/libdwP.h b/libdw/libdwP.h index a4f26b82..9dce10e5 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -804,15 +804,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; @@ -821,7 +834,9 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) if (die->abbrev == NULL) die->abbrev = __libdw_findabbrev (die->cu, code); } - return die->abbrev; + + rwlock_unlock (die->cu->abbrev_lock); + return (Dwarf_Abbrev *) die->abbrev; } /* Helper functions for form handling. */