diff options
author | Alexander Monakov <amonakov@ispras.ru> | 2013-07-23 13:17:10 +0400 |
---|---|---|
committer | Alexander Monakov <amonakov@gcc.gnu.org> | 2013-07-23 13:17:10 +0400 |
commit | 78625ce608eae8e2d5fc5c5ceef5a4dfd0d2dc2e (patch) | |
tree | 2632b6242b9dd32951ac718cc22e38dc6297dff5 /libbacktrace | |
parent | 0153887c3da394fd78973c50a457efc164a6758d (diff) | |
download | gcc-78625ce608eae8e2d5fc5c5ceef5a4dfd0d2dc2e.tar.gz |
elf.c (elf_syminfo): Loop over the elf_syminfo_data chain.
* elf.c (elf_syminfo): Loop over the elf_syminfo_data chain.
From-SVN: r201159
Diffstat (limited to 'libbacktrace')
-rw-r--r-- | libbacktrace/ChangeLog | 4 | ||||
-rw-r--r-- | libbacktrace/elf.c | 44 |
2 files changed, 43 insertions, 5 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog index 1f1d21e4829..d6f7205f1d1 100644 --- a/libbacktrace/ChangeLog +++ b/libbacktrace/ChangeLog @@ -1,5 +1,9 @@ 2013-07-23 Alexander Monakov <amonakov@ispras.ru> + * elf.c (elf_syminfo): Loop over the elf_syminfo_data chain. + +2013-07-23 Alexander Monakov <amonakov@ispras.ru> + * elf.c (backtrace_initialize): Pass elf_fileline_fn to dl_iterate_phdr callbacks. diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c index 36761899458..c1dbc5492e0 100644 --- a/libbacktrace/elf.c +++ b/libbacktrace/elf.c @@ -454,12 +454,46 @@ elf_syminfo (struct backtrace_state *state, uintptr_t pc, void *data) { struct elf_syminfo_data *edata; - struct elf_symbol *sym; + struct elf_symbol *sym = NULL; + + if (!state->threaded) + { + for (edata = (struct elf_syminfo_data *) state->syminfo_data; + edata != NULL; + edata = edata->next) + { + sym = ((struct elf_symbol *) + bsearch (&pc, edata->symbols, edata->count, + sizeof (struct elf_symbol), elf_symbol_search)); + if (sym != NULL) + break; + } + } + else + { + struct elf_syminfo_data **pp; + + pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data; + while (1) + { + edata = *pp; + /* Atomic load. */ + while (!__sync_bool_compare_and_swap (pp, edata, edata)) + edata = *pp; + + if (edata == NULL) + break; + + sym = ((struct elf_symbol *) + bsearch (&pc, edata->symbols, edata->count, + sizeof (struct elf_symbol), elf_symbol_search)); + if (sym != NULL) + break; + + pp = &edata->next; + } + } - edata = (struct elf_syminfo_data *) state->syminfo_data; - sym = ((struct elf_symbol *) - bsearch (&pc, edata->symbols, edata->count, - sizeof (struct elf_symbol), elf_symbol_search)); if (sym == NULL) callback (data, pc, NULL, 0); else |