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.
This commit is contained in:
Alan Modra
2013-02-08 07:04:50 +00:00
parent 02acbe2250
commit 619a703ea3
3 changed files with 41 additions and 23 deletions

View 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> 2013-02-07 H.J. Lu <hongjiu.lu@intel.com>
PR ld/15107 PR ld/15107

View File

@ -1598,6 +1598,9 @@ struct elf_obj_tdata
/* A place to stash dwarf2 info for this bfd. */ /* A place to stash dwarf2 info for this bfd. */
void *dwarf2_find_line_info; 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 /* An array of stub sections indexed by symbol number, used by the
MIPS ELF linker. FIXME: We should figure out some way to only MIPS ELF linker. FIXME: We should figure out some way to only
include this field for a MIPS ELF target. */ include this field for a MIPS ELF target. */

View File

@ -7504,20 +7504,29 @@ elf_find_function (bfd *abfd,
const char **filename_ptr, const char **filename_ptr,
const char **functionname_ptr) const char **functionname_ptr)
{ {
static asection *last_section; struct elf_find_function_cache
static asymbol **last_symbols; {
static asymbol *func; asection *last_section;
static const char *filename; asymbol *func;
static bfd_size_type func_size; const char *filename;
bfd_size_type func_size;
} *cache;
if (symbols == NULL) if (symbols == NULL)
return FALSE; return FALSE;
if (last_section != section cache = elf_tdata (abfd)->elf_find_function_cache;
|| last_symbols != symbols if (cache == NULL)
|| func == NULL {
|| offset < func->value cache = bfd_zalloc (abfd, sizeof (*cache));
|| offset >= func->value + func_size) 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; asymbol *file;
bfd_vma low_func; bfd_vma low_func;
@ -7533,14 +7542,13 @@ elf_find_function (bfd *abfd,
enum { nothing_seen, symbol_seen, file_after_symbol_seen } state; enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
const struct elf_backend_data *bed = get_elf_backend_data (abfd); const struct elf_backend_data *bed = get_elf_backend_data (abfd);
filename = NULL;
func = NULL;
file = NULL; file = NULL;
low_func = 0; low_func = 0;
state = nothing_seen; state = nothing_seen;
func_size = 0; cache->filename = NULL;
last_section = section; cache->func = NULL;
last_symbols = symbols; cache->func_size = 0;
cache->last_section = section;
for (p = symbols; *p != NULL; p++) for (p = symbols; *p != NULL; p++)
{ {
@ -7561,29 +7569,29 @@ elf_find_function (bfd *abfd,
&& code_off <= offset && code_off <= offset
&& (code_off > low_func && (code_off > low_func
|| (code_off == low_func || (code_off == low_func
&& size > func_size))) && size > cache->func_size)))
{ {
func = sym; cache->func = sym;
func_size = size; cache->func_size = size;
cache->filename = NULL;
low_func = code_off; low_func = code_off;
filename = NULL;
if (file != NULL if (file != NULL
&& ((sym->flags & BSF_LOCAL) != 0 && ((sym->flags & BSF_LOCAL) != 0
|| state != file_after_symbol_seen)) || state != file_after_symbol_seen))
filename = bfd_asymbol_name (file); cache->filename = bfd_asymbol_name (file);
} }
if (state == nothing_seen) if (state == nothing_seen)
state = symbol_seen; state = symbol_seen;
} }
} }
if (func == NULL) if (cache->func == NULL)
return FALSE; return FALSE;
if (filename_ptr) if (filename_ptr)
*filename_ptr = filename; *filename_ptr = cache->filename;
if (functionname_ptr) if (functionname_ptr)
*functionname_ptr = bfd_asymbol_name (func); *functionname_ptr = bfd_asymbol_name (cache->func);
return TRUE; return TRUE;
} }