../libcpu/libcpu_pic.a libdw_pic.a ../libdwelf/libdwelf_pic.a \
../libdwfl/libdwfl_pic.a ../libdwfl_stacktrace/libdwfl_stacktrace_pic.a
libdw_so_DEPS = ../lib/libeu.a ../libelf/libelf.so
-libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(fts_LIBS) $(obstack_LIBS) $(zip_LIBS) -pthread
+libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(fts_LIBS) \
+ $(obstack_LIBS) $(zip_LIBS) -pthread -latomic
libdw.so: $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-Wl,--soname,$@.$(VERSION),--enable-new-dtags \
result->fake_loc_cu->version = 4;
result->fake_loc_cu->split = NULL;
eu_search_tree_init (&result->fake_loc_cu->locs_tree);
- rwlock_init (result->fake_loc_cu->abbrev_lock);
rwlock_init (result->fake_loc_cu->split_lock);
+ mutex_init (result->fake_loc_cu->abbrev_lock);
mutex_init (result->fake_loc_cu->src_lock);
mutex_init (result->fake_loc_cu->str_off_base_lock);
mutex_init (result->fake_loc_cu->intern_lock);
result->fake_loclists_cu->version = 5;
result->fake_loclists_cu->split = NULL;
eu_search_tree_init (&result->fake_loclists_cu->locs_tree);
- rwlock_init (result->fake_loclists_cu->abbrev_lock);
rwlock_init (result->fake_loclists_cu->split_lock);
+ mutex_init (result->fake_loclists_cu->abbrev_lock);
mutex_init (result->fake_loclists_cu->src_lock);
mutex_init (result->fake_loclists_cu->str_off_base_lock);
mutex_init (result->fake_loclists_cu->intern_lock);
result->fake_addr_cu->version = 5;
result->fake_addr_cu->split = NULL;
eu_search_tree_init (&result->fake_addr_cu->locs_tree);
- rwlock_init (result->fake_addr_cu->abbrev_lock);
rwlock_init (result->fake_addr_cu->split_lock);
+ mutex_init (result->fake_addr_cu->abbrev_lock);
mutex_init (result->fake_addr_cu->src_lock);
mutex_init (result->fake_addr_cu->str_off_base_lock);
mutex_init (result->fake_addr_cu->intern_lock);
Dwarf_Files *files;
size_t nfiles;
- if (INTUSE(dwarf_getsrcfiles) (&CUDIE (attr_mem.cu), &files, &nfiles) != 0)
+ Dwarf_Die cudie = CUDIE (attr_mem.cu);
+ if (INTUSE(dwarf_getsrcfiles) (&cudie, &files, &nfiles) != 0)
return NULL;
if (idx >= nfiles)
struct Dwarf_CU *p = (struct Dwarf_CU *) arg;
eu_search_tree_fini (&p->locs_tree, noop_free);
- rwlock_fini (p->abbrev_lock);
rwlock_fini (p->split_lock);
+ mutex_fini (p->abbrev_lock);
mutex_fini (p->src_lock);
mutex_fini (p->str_off_base_lock);
mutex_fini (p->intern_lock);
static int
getfiles (Dwarf_Die *die, Dwarf_Files **files)
{
- return INTUSE(dwarf_getsrcfiles) (&CUDIE (die->cu), files, NULL);
+ Dwarf_Die cudie = CUDIE (die->cu);
+ return INTUSE(dwarf_getsrcfiles) (&cudie, files, NULL);
}
/* Fetch an attribute that should have a constant integer form. */
/* Find the next entry. It gets automatically added to the
hash table. */
+ mutex_lock (cu->abbrev_lock);
abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length);
+
if (abb == NULL || abb == DWARF_END_ABBREV)
{
/* Make sure we do not try to search for it again. */
cu->last_abbrev_offset = (size_t) -1l;
+ mutex_unlock (cu->abbrev_lock);
return DWARF_END_ABBREV;
}
cu->last_abbrev_offset += length;
+ mutex_unlock (cu->abbrev_lock);
/* Is this the code we are looking for? */
if (abb->code == code)
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. Covers __libdw_die_abbrev. */
- rwlock_define(, abbrev_lock);
-
/* Synchronize access to the split member of this Dwarf_CU.
Covers __libdw_find_split_unit. */
rwlock_define(, split_lock);
+ /* Synchronize access to the last_abbrev_offset member of a Dwarf_Die
+ that refers to this Dwarf_CU. */
+ mutex_define(, abbrev_lock);
+
/* Synchronize access to the lines and files members.
Covers dwarf_getsrclines and dwarf_getsrcfiles. */
mutex_define(, src_lock);
__nonnull_attribute__ (1)
__libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
{
+ Dwarf_Abbrev *end_abbrev = DWARF_END_ABBREV;
+ Dwarf_Abbrev *expected = (Dwarf_Abbrev *) NULL;
+
if (unlikely (die->cu == NULL))
{
- die->abbrev = DWARF_END_ABBREV;
- return DWARF_END_ABBREV;
+ __atomic_compare_exchange_n (&die->abbrev, &expected, end_abbrev, false,
+ __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
+ return end_abbrev;
}
- rwlock_wrlock (die->cu->abbrev_lock);
+ Dwarf_Abbrev *abbrev = __atomic_load_n (&die->abbrev, __ATOMIC_ACQUIRE);
+ if (abbrev != NULL && readp == NULL)
+ return abbrev;
- /* Do we need to get the abbreviation, or need to read after the code? */
- if (die->abbrev == NULL || readp != NULL)
+ /* We need to get the abbreviation or need to read after the code. */
+ unsigned int code;
+ const unsigned char *addr = die->addr;
+ if (addr >= (const unsigned char *) die->cu->endp)
{
- /* Get the abbreviation code. */
- unsigned int code;
- const unsigned char *addr = die->addr;
-
- if (addr >= (const unsigned char *) die->cu->endp)
- {
- die->abbrev = DWARF_END_ABBREV;
- rwlock_unlock (die->cu->abbrev_lock);
- return DWARF_END_ABBREV;
- }
+ __atomic_compare_exchange_n (&die->abbrev, &expected, end_abbrev, false,
+ __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
+ return end_abbrev;
+ }
- get_uleb128 (code, addr, die->cu->endp);
- if (readp != NULL)
- *readp = addr;
+ /* Get the abbreviation code. */
+ get_uleb128 (code, addr, die->cu->endp);
+ if (readp != NULL)
+ *readp = addr;
- /* Find the abbreviation. */
- if (die->abbrev == NULL)
- die->abbrev = __libdw_findabbrev (die->cu, code);
- }
+ if (abbrev != NULL)
+ return abbrev;
- Dwarf_Abbrev *result = die->abbrev;
- rwlock_unlock (die->cu->abbrev_lock);
+ /* Find the abbreviation. */
+ abbrev = __libdw_findabbrev (die->cu, code);
+ __atomic_compare_exchange_n (&die->abbrev, &expected, abbrev, false,
+ __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
- return result;
+ return abbrev;
}
/* Helper functions for form handling. */
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);
rwlock_init (newp->split_lock);
+ mutex_init (newp->abbrev_lock);
mutex_init (newp->src_lock);
mutex_init (newp->str_off_base_lock);
mutex_init (newp->intern_lock);