PR binutils/15106
authorAlan Modra <amodra@gmail.com>
Fri, 8 Feb 2013 07:04:50 +0000 (07:04 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 8 Feb 2013 07:04:50 +0000 (07:04 +0000)
* 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.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c

index 4c936117c163a33b3bb345362c106984ecb5ae62..eb723b3f044a289995c5e2e0def29c4fc12bd3a7 100644 (file)
@@ -1,3 +1,10 @@
+2013-02-08  Alan Modra  <amodra@gmail.com>
+
+       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.
+
 2013-02-07  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/15107
index 9b38317582395ef718c6d3453155cc8a95536d8f..e3876257d9d919f89b56f9b35d8af7b60adbb291 100644 (file)
@@ -1598,6 +1598,9 @@ struct elf_obj_tdata
   /* A place to stash dwarf2 info for this bfd.  */
   void *dwarf2_find_line_info;
 
+  /* Stash away info for yet another find line/function variant.  */
+  void *elf_find_function_cache;
+
   /* An array of stub sections indexed by symbol number, used by the
      MIPS ELF linker.  FIXME: We should figure out some way to only
      include this field for a MIPS ELF target.  */
index 9d6ff318924a3ca3ef0eb1deddd709c35b465e50..380f6eff2a696f8e0b628efb53c3740e97c4a4d8 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -7504,20 +7504,29 @@ elf_find_function (bfd *abfd,
                   const char **filename_ptr,
                   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;
+  struct elf_find_function_cache
+  {
+    asection *last_section;
+    asymbol *func;
+    const char *filename;
+    bfd_size_type func_size;
+  } *cache;
 
   if (symbols == NULL)
     return FALSE;
 
-  if (last_section != section
-      || last_symbols != symbols
-      || func == NULL
-      || offset < func->value
-      || offset >= func->value + func_size)
+  cache = elf_tdata (abfd)->elf_find_function_cache;
+  if (cache == NULL)
+    {
+      cache = bfd_zalloc (abfd, sizeof (*cache));
+      elf_tdata (abfd)->elf_find_function_cache = cache;
+      if (cache == NULL)
+       return FALSE;
+    }
+  if (cache->last_section != section
+      || cache->func == NULL
+      || offset < cache->func->value
+      || offset >= cache->func->value + cache->func_size)
     {
       asymbol *file;
       bfd_vma low_func;
@@ -7533,14 +7542,13 @@ elf_find_function (bfd *abfd,
       enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
       const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
-      filename = NULL;
-      func = NULL;
       file = NULL;
       low_func = 0;
       state = nothing_seen;
-      func_size = 0;
-      last_section = section;
-      last_symbols = symbols;
+      cache->filename = NULL;
+      cache->func = NULL;
+      cache->func_size = 0;
+      cache->last_section = section;
 
       for (p = symbols; *p != NULL; p++)
        {
@@ -7561,29 +7569,29 @@ elf_find_function (bfd *abfd,
              && code_off <= offset
              && (code_off > low_func
                  || (code_off == low_func
-                     && size > func_size)))
+                     && size > cache->func_size)))
            {
-             func = sym;
-             func_size = size;
+             cache->func = sym;
+             cache->func_size = size;
+             cache->filename = NULL;
              low_func = code_off;
-             filename = NULL;
              if (file != NULL
                  && ((sym->flags & BSF_LOCAL) != 0
                      || state != file_after_symbol_seen))
-               filename = bfd_asymbol_name (file);
+               cache->filename = bfd_asymbol_name (file);
            }
          if (state == nothing_seen)
            state = symbol_seen;
        }
     }
 
-  if (func == NULL)
+  if (cache->func == NULL)
     return FALSE;
 
   if (filename_ptr)
-    *filename_ptr = filename;
+    *filename_ptr = cache->filename;
   if (functionname_ptr)
-    *functionname_ptr = bfd_asymbol_name (func);
+    *functionname_ptr = bfd_asymbol_name (cache->func);
 
   return TRUE;
 }