Use binary search on dynamic relocations
Replace linear search with binary search on dynamic relocations. After finding a match, scan backward to the first matching relocation, then scan forward for a matching relocation with non-absolute symbol. On Fedora 27 x86-64, time for "objdump -d" on libxul.so from RHEL 7.4 x86-64 went from 134.46user 0.12system 2:15.03elapsed to 8.49user 0.14system 0:08.64elapsed PR binutils/22911 * objdump.c (is_significant_symbol_name): Return TRUE for all .plt* sections. (find_symbol_for_address): Replace linear search with binary search on dynamic relocations.
This commit is contained in:
parent
3dea1ef72c
commit
0e70b27ba9
2 changed files with 50 additions and 19 deletions
|
@ -1,3 +1,11 @@
|
|||
2018-03-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR binutils/22911
|
||||
* objdump.c (is_significant_symbol_name): Return TRUE for all
|
||||
.plt* sections.
|
||||
(find_symbol_for_address): Replace linear search with binary
|
||||
search on dynamic relocations.
|
||||
|
||||
2018-03-01 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 22905
|
||||
|
|
|
@ -664,9 +664,7 @@ slurp_dynamic_symtab (bfd *abfd)
|
|||
static bfd_boolean
|
||||
is_significant_symbol_name (const char * name)
|
||||
{
|
||||
return strcmp (name, ".plt") == 0
|
||||
|| strcmp (name, ".got") == 0
|
||||
|| strcmp (name, ".plt.got") == 0;
|
||||
return strncmp (name, ".plt", 4) == 0 || strcmp (name, ".got") == 0;
|
||||
}
|
||||
|
||||
/* Filter out (in place) symbols that are useless for disassembly.
|
||||
|
@ -937,6 +935,7 @@ find_symbol_for_address (bfd_vma vma,
|
|||
asection *sec;
|
||||
unsigned int opb;
|
||||
bfd_boolean want_section;
|
||||
long rel_count;
|
||||
|
||||
if (sorted_symcount < 1)
|
||||
return NULL;
|
||||
|
@ -1065,33 +1064,57 @@ find_symbol_for_address (bfd_vma vma,
|
|||
and we have dynamic relocations available, then we can produce
|
||||
a better result by matching a relocation to the address and
|
||||
using the symbol associated with that relocation. */
|
||||
rel_count = aux->dynrelcount;
|
||||
if (!want_section
|
||||
&& aux->dynrelbuf != NULL
|
||||
&& sorted_syms[thisplace]->value != vma
|
||||
&& rel_count > 0
|
||||
&& aux->dynrelbuf != NULL
|
||||
&& aux->dynrelbuf[0]->address <= vma
|
||||
&& aux->dynrelbuf[rel_count - 1]->address >= vma
|
||||
/* If we have matched a synthetic symbol, then stick with that. */
|
||||
&& (sorted_syms[thisplace]->flags & BSF_SYNTHETIC) == 0)
|
||||
{
|
||||
long rel_count;
|
||||
arelent ** rel_pp;
|
||||
arelent ** rel_low;
|
||||
arelent ** rel_high;
|
||||
|
||||
for (rel_count = aux->dynrelcount, rel_pp = aux->dynrelbuf;
|
||||
rel_count--;)
|
||||
rel_low = aux->dynrelbuf;
|
||||
rel_high = rel_low + rel_count - 1;
|
||||
while (rel_low <= rel_high)
|
||||
{
|
||||
arelent * rel = rel_pp[rel_count];
|
||||
arelent **rel_mid = &rel_low[(rel_high - rel_low) / 2];
|
||||
arelent * rel = *rel_mid;
|
||||
|
||||
if (rel->address == vma
|
||||
&& rel->sym_ptr_ptr != NULL
|
||||
/* Absolute relocations do not provide a more helpful symbolic address. */
|
||||
&& ! bfd_is_abs_section ((* rel->sym_ptr_ptr)->section))
|
||||
if (rel->address == vma)
|
||||
{
|
||||
if (place != NULL)
|
||||
* place = thisplace;
|
||||
return * rel->sym_ptr_ptr;
|
||||
/* Absolute relocations do not provide a more helpful
|
||||
symbolic address. Find a non-absolute relocation
|
||||
with the same address. */
|
||||
arelent **rel_vma = rel_mid;
|
||||
for (rel_mid--;
|
||||
rel_mid >= rel_low && rel_mid[0]->address == vma;
|
||||
rel_mid--)
|
||||
rel_vma = rel_mid;
|
||||
|
||||
for (; rel_vma <= rel_high && rel_vma[0]->address == vma;
|
||||
rel_vma++)
|
||||
{
|
||||
rel = *rel_vma;
|
||||
if (rel->sym_ptr_ptr != NULL
|
||||
&& ! bfd_is_abs_section ((* rel->sym_ptr_ptr)->section))
|
||||
{
|
||||
if (place != NULL)
|
||||
* place = thisplace;
|
||||
return * rel->sym_ptr_ptr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* We are scanning backwards, so if we go below the target address
|
||||
we have failed. */
|
||||
if (rel_pp[rel_count]->address < vma)
|
||||
if (vma < rel->address)
|
||||
rel_high = rel_mid;
|
||||
else if (vma >= rel_mid[1]->address)
|
||||
rel_low = rel_mid + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue