summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-23 09:17:10 +0000
committeramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-23 09:17:10 +0000
commit645142448ee8b232fecfa243a06a2b375a97167b (patch)
tree2632b6242b9dd32951ac718cc22e38dc6297dff5
parent5d62aeb5056799ce6dec46b0fb6ba9ac4516f198 (diff)
downloadgcc-645142448ee8b232fecfa243a06a2b375a97167b.tar.gz
* elf.c (elf_syminfo): Loop over the elf_syminfo_data chain.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201159 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libbacktrace/ChangeLog4
-rw-r--r--libbacktrace/elf.c44
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