summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2012-04-11 14:16:09 +0000
committerNick Clifton <nickc@redhat.com>2012-04-11 14:16:09 +0000
commit4841cf0c4cb8a97e59f2a1c800346b725cb77e6a (patch)
tree0fdfbc12d6d087db1d2beccbb388292569baa2d1
parent1233b4a775cd7a584b8aac3a3a5b5055c0707528 (diff)
downloadbinutils-gdb-4841cf0c4cb8a97e59f2a1c800346b725cb77e6a.tar.gz
PR binutils/13897
* elf64-ppc.c (opd_entry_value): When dealing with sections without relocs, keep the last section loaded in order to avoid unnecessary reloads.
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf64-ppc.c38
2 files changed, 35 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6d1294408ac..74f8c3a3559 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2012-04-11 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/13897
+ * elf64-ppc.c (opd_entry_value): When dealing with sections
+ without relocs, keep the last section loaded in order to avoid
+ unnecessary reloads.
+
2012-04-09 Roland McGrath <mcgrathr@google.com>
* elf.c (_bfd_elf_map_sections_to_segments): Set INFO->user_phdrs.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index e7a01c2215e..3b03db4dd7a 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5533,28 +5533,46 @@ opd_entry_value (asection *opd_sec,
at a final linked executable with addr2line or somesuch. */
if (opd_sec->reloc_count == 0)
{
- char buf[8];
-
+ /* PR 13897: Cache the loaded section to speed up the search. */
+ static asection * buf_sec = NULL;
+ static char buf[8];
+ static bfd_vma buf_val = 0;
+ static asection * buf_likely = NULL;
+
+ if (buf_sec == opd_sec)
+ {
+ if (code_sec != NULL)
+ * code_sec = buf_likely;
+ if (code_off != NULL && buf_likely != NULL)
+ * code_off = buf_val - buf_likely->vma;
+ return buf_val;
+ }
+
if (!bfd_get_section_contents (opd_bfd, opd_sec, buf, offset, 8))
return (bfd_vma) -1;
+ buf_sec = opd_sec;
- val = bfd_get_64 (opd_bfd, buf);
+ buf_val = bfd_get_64 (opd_bfd, buf);
if (code_sec != NULL)
{
- asection *sec, *likely = NULL;
+ asection *sec;
+
+ buf_likely = NULL;
for (sec = opd_bfd->sections; sec != NULL; sec = sec->next)
- if (sec->vma <= val
+ if (sec->vma <= buf_val
&& (sec->flags & SEC_LOAD) != 0
&& (sec->flags & SEC_ALLOC) != 0)
- likely = sec;
- if (likely != NULL)
+ buf_likely = sec;
+ if (buf_likely != NULL)
{
- *code_sec = likely;
+ *code_sec = buf_likely;
if (code_off != NULL)
- *code_off = val - likely->vma;
+ *code_off = buf_val - buf_likely->vma;
}
}
- return val;
+ else
+ buf_likely = NULL;
+ return buf_val;
}
BFD_ASSERT (is_ppc64_elf (opd_bfd));