+ /* If we have not found an exact match for the specified address
+ 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
+ && 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)
+ {
+ arelent ** rel_low;
+ arelent ** rel_high;
+
+ rel_low = aux->dynrelbuf;
+ rel_high = rel_low + rel_count - 1;
+ while (rel_low <= rel_high)
+ {
+ arelent **rel_mid = &rel_low[(rel_high - rel_low) / 2];
+ arelent * rel = *rel_mid;
+
+ if (rel->address == vma)
+ {
+ /* 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;
+ }
+
+ if (vma < rel->address)
+ rel_high = rel_mid;
+ else if (vma >= rel_mid[1]->address)
+ rel_low = rel_mid + 1;
+ else
+ break;
+ }
+ }
+