Patchwork libbacktrace: walk the elf_syminfo_data chain in elf_syminfo

login
register
mail settings
Submitter Alexander Monakov
Date July 22, 2013, 1:26 p.m.
Message ID <alpine.LNX.2.00.1307221718150.1061@monopod.intra.ispras.ru>
Download mbox | patch
Permalink /patch/260696/
State New
Headers show

Comments

Alexander Monakov - July 22, 2013, 1:26 p.m.
Hello,

this fixes a bug (found by inspection) that would prevent elf_syminfo from
looking up symbols defined in modules other than the executable.

Bootstrapped and regtested together with the next patch on x86_64-linux
(excluding Java, including Go), OK for trunk?

libbacktrace/Changelog:
2013-07-22  Alexander Monakov  <amonakov@ispras.ru>

	* elf.c (elf_syminfo): Loop over the elf_syminfo_data chain.
Ian Taylor - July 22, 2013, 3:29 p.m.
On Mon, Jul 22, 2013 at 6:26 AM, Alexander Monakov <amonakov@ispras.ru> wrote:
>
> this fixes a bug (found by inspection) that would prevent elf_syminfo from
> looking up symbols defined in modules other than the executable.
>
> Bootstrapped and regtested together with the next patch on x86_64-linux
> (excluding Java, including Go), OK for trunk?
>
> libbacktrace/Changelog:
> 2013-07-22  Alexander Monakov  <amonakov@ispras.ru>
>
>         * elf.c (elf_syminfo): Loop over the elf_syminfo_data chain.

Thanks for noticing the problem.  This patch isn't enough by itself.
The code has to protect itself against the list changing in
mid-stream.  See dwarf_fileline in dwarf.c.

Ian

Patch

diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index ef9bcdf..a90afaa 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -454,12 +454,15 @@  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;
+
+  for (edata = (struct elf_syminfo_data *) state->syminfo_data;
+       edata && sym == NULL;
+       edata = edata->next)
+    sym = ((struct elf_symbol *)
+          bsearch (&pc, edata->symbols, edata->count,
+                   sizeof (struct elf_symbol), elf_symbol_search));
 
-  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