* [binutils-gdb] Enhance better_fit() function to prefer function symbols over non-function symbols.
@ 2023-02-24 12:26 Nick Clifton
0 siblings, 0 replies; only message in thread
From: Nick Clifton @ 2023-02-24 12:26 UTC (permalink / raw)
To: bfd-cvs
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7b1792f543161424ce60ff28b9d012a590e220b2
commit 7b1792f543161424ce60ff28b9d012a590e220b2
Author: Nick Clifton <nickc@redhat.com>
Date: Fri Feb 24 12:25:50 2023 +0000
Enhance better_fit() function to prefer function symbols over non-function symbols.
Diff:
---
bfd/dwarf2.c | 52 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 37 insertions(+), 15 deletions(-)
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index ac7c4f63c57..15862dc2037 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -6146,12 +6146,13 @@ typedef struct elf_find_function_cache
} elf_find_function_cache;
-/* Returns TRUE if the symbol with address CODE_OFF and size CODE_SIZE
+/* Returns TRUE if symbol SYM with address CODE_OFF and size CODE_SIZE
is a better fit to match OFFSET than whatever is currenly stored in
CACHE. */
static inline bool
better_fit (elf_find_function_cache * cache,
+ asymbol * sym,
bfd_vma code_off,
bfd_size_type code_size,
bfd_vma offset)
@@ -6169,24 +6170,45 @@ better_fit (elf_find_function_cache * cache,
if (code_off > cache->code_off)
return true;
+ /* assert (code_off == cache->code_off); */
+
/* If our current best fit does not actually reach the desired
offset... */
if (cache->code_off + cache->code_size <= offset)
- {
- /* Then return whichever candidate covers more area. */
- return code_size > cache->code_size;
- }
+ /* ... then return whichever candidate covers
+ more area and hence gets closer to OFFSET. */
+ return code_size > cache->code_size;
- /* If the new symbol also covers the desired offset... */
- if (code_off + code_size > offset)
- {
- /* Then choose whichever is smaller. */
- /* FIXME: Maybe prefer LOCAL over GLOBAL or something else here ? */
- return code_size < cache->code_size;
- }
+ /* The current cache'd symbol covers OFFSET. */
- /* Otherwise the cached symbol is better. */
- return false;
+ /* If the new symbol does not cover the desired offset then skip it. */
+ if (code_off + code_size <= offset)
+ return false;
+
+ /* Both symbols cover OFFSET. */
+
+ /* Prefer functions over non-functions. */
+ flagword cache_flags = cache->func->flags;
+ flagword sym_flags = sym->flags;
+
+ if ((cache_flags & BSF_FUNCTION) && ((sym_flags & BSF_FUNCTION) == 0))
+ return false;
+ if ((sym_flags & BSF_FUNCTION) && ((cache_flags & BSF_FUNCTION) == 0))
+ return true;
+
+ /* FIXME: Should we choose LOCAL over GLOBAL ? */
+
+ /* Prefer typed symbols over notyped. */
+ int cache_type = ELF_ST_TYPE (((elf_symbol_type *) cache->func)->internal_elf_sym.st_info);
+ int sym_type = ELF_ST_TYPE (((elf_symbol_type *) sym)->internal_elf_sym.st_info);
+
+ if (cache_type == STT_NOTYPE && sym_type != STT_NOTYPE)
+ return true;
+ if (cache_type != STT_NOTYPE && sym_type == STT_NOTYPE)
+ return false;
+
+ /* Otherwise choose whichever symbol covers a smaller area. */
+ return code_size < cache->code_size;
}
/* Find the function to a particular section and offset,
@@ -6264,7 +6286,7 @@ _bfd_elf_find_function (bfd *abfd,
if (size == 0)
continue;
- if (better_fit (cache, code_off, size, offset))
+ if (better_fit (cache, sym, code_off, size, offset))
{
cache->func = sym;
cache->code_size = size;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-02-24 12:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-24 12:26 [binutils-gdb] Enhance better_fit() function to prefer function symbols over non-function symbols Nick Clifton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).