Bug 15106

Summary: Segfault in elf_find_function
Product: binutils Reporter: Roberto Agostino Vitillo <ra.vitillo>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: amodra
Priority: P2    
Version: 2.23   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Roberto Agostino Vitillo 2013-02-06 17:55:35 UTC
The caching of the last function sym info in elf_find_function causes a segfault when last_section == section but the pointer to symbols has changed from the last invocation and func is not a valid pointer anymore.

The following patch fixes this bug:
diff --git a/elf.c b/elf.c
--- a/elf.c
+++ b/elf.c
@@ -7475,6 +7475,7 @@ elf_find_function (bfd *abfd,
                   const char **functionname_ptr)
 {
   static asection *last_section;
+  static asymbol **last_symbols;
   static asymbol *func;
   static const char *filename;
   static bfd_size_type func_size;
@@ -7483,6 +7484,7 @@ elf_find_function (bfd *abfd,
     return FALSE;
 
   if (last_section != section
+      || last_symbols != symbols
       || func == NULL
       || offset < func->value
       || offset >= func->value + func_size)
@@ -7531,6 +7533,7 @@ elf_find_function (bfd *abfd,
                      && size > func_size)))
            {
              func = sym;
+             last_symbols = symbols;
              func_size = size;
              low_func = code_off;
Comment 1 Alan Modra 2013-02-07 04:16:19 UTC
Hmm, how did you manage to call elf_find_function with a different set of symbols?
Comment 2 Sourceware Commits 2013-02-07 04:20:42 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2013-02-07 04:20:32

Modified files:
	bfd            : ChangeLog elf.c 

Log message:
	PR binutils/15106
	* elf.c (elf_find_function): Don't cache if symbols change.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5934&r2=1.5935
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf.c.diff?cvsroot=src&r1=1.582&r2=1.583
Comment 3 Sourceware Commits 2013-02-07 04:21:47 UTC
CVSROOT:	/cvs/src
Module name:	src
Branch: 	binutils-2_23-branch
Changes by:	amodra@sourceware.org	2013-02-07 04:21:35

Modified files:
	bfd            : ChangeLog elf.c 

Log message:
	PR binutils/15106
	* elf.c (elf_find_function): Don't cache if symbols change.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&only_with_tag=binutils-2_23-branch&r1=1.5758.2.42&r2=1.5758.2.43
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf.c.diff?cvsroot=src&only_with_tag=binutils-2_23-branch&r1=1.568.2.1&r2=1.568.2.2
Comment 4 Alan Modra 2013-02-07 04:26:07 UTC
Fixed
Comment 5 Roberto Agostino Vitillo 2013-02-07 18:32:30 UTC
In my application I open and close continuously DSOs. In rare cases it happens that after closing and opening a DSO, the pointer to a certain section within the new DSO has the same value as the old pointer.
Even with my trivial change there is still the remote possibility that you could have the same values for the pointers to section and symbols. One way to fix this cleanly would be to associate the cache to the bfd struct, for example.
Comment 6 Alan Modra 2013-02-07 23:45:33 UTC
Right, I should not have used static vars..
Comment 7 Sourceware Commits 2013-02-08 07:04:56 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2013-02-08 07:04:50

Modified files:
	bfd            : ChangeLog elf-bfd.h elf.c 

Log message:
	PR binutils/15106
	* elf-bfd.h (struct elf_obj_tdata): Add elf_find_function_cache.
	* elf.c (elf_find_function): Revert last change.  Use new
	tdata field rather than static vars for cache.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5936&r2=1.5937
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf-bfd.h.diff?cvsroot=src&r1=1.357&r2=1.358
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf.c.diff?cvsroot=src&r1=1.583&r2=1.584
Comment 8 Sourceware Commits 2013-02-08 07:05:18 UTC
CVSROOT:	/cvs/src
Module name:	src
Branch: 	binutils-2_23-branch
Changes by:	amodra@sourceware.org	2013-02-08 07:05:11

Modified files:
	bfd            : ChangeLog elf-bfd.h elf.c 

Log message:
	PR binutils/15106
	* elf-bfd.h (struct elf_obj_tdata): Add elf_find_function_cache.
	* elf.c (elf_find_function): Revert last change.  Use new
	tdata field rather than static vars for cache.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&only_with_tag=binutils-2_23-branch&r1=1.5758.2.43&r2=1.5758.2.44
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf-bfd.h.diff?cvsroot=src&only_with_tag=binutils-2_23-branch&r1=1.343.2.3&r2=1.343.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf.c.diff?cvsroot=src&only_with_tag=binutils-2_23-branch&r1=1.568.2.2&r2=1.568.2.3