aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-06-01 12:26:55 +0000
committerAlan Modra <amodra@gmail.com>2012-06-01 12:26:55 +0000
commitee1e4edefed84ff94223b700deaf138eb5b5e40f (patch)
tree314b6d672c5f79a90ac7ea0e1d22b30c18b7a787
parent145fa769e6ba89ed4f326959ae9d94445667283d (diff)
downloadbinutils-ee1e4edefed84ff94223b700deaf138eb5b5e40f.zip
binutils-ee1e4edefed84ff94223b700deaf138eb5b5e40f.tar.gz
binutils-ee1e4edefed84ff94223b700deaf138eb5b5e40f.tar.bz2
PR binutils/13897
* elf64-ppc.c (opd_entry_value): Rewrite cache code.
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf64-ppc.c69
2 files changed, 38 insertions, 36 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 90f24bc..2cda278 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2012-06-01 Alan Modra <amodra@gmail.com>
+
+ PR binutils/13897
+ * elf64-ppc.c (opd_entry_value): Rewrite cache code.
+
2012-05-29 Tom Tromey <tromey@redhat.com>
* opncls.c (bfd_fopen): Always close fd on failure.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 79f551d..984d343 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5533,46 +5533,43 @@ opd_entry_value (asection *opd_sec,
at a final linked executable with addr2line or somesuch. */
if (opd_sec->reloc_count == 0)
{
- /* 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)
+ static asection *last_opd_sec, *last_code_sec;
+ static bfd_vma last_opd_off, last_entry_vma;
+ static bfd_boolean sec_search_done;
+
+ if (last_opd_sec != opd_sec
+ || last_opd_off != offset
+ || (code_sec != NULL && !sec_search_done))
{
+ char buf[8];
+
+ if (!bfd_get_section_contents (opd_bfd, opd_sec, buf, offset, 8))
+ return (bfd_vma) -1;
+
+ last_opd_sec = opd_sec;
+ last_opd_off = offset;
+ last_entry_vma = bfd_get_64 (opd_bfd, buf);
+ sec_search_done = FALSE;
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;
-
- buf_val = bfd_get_64 (opd_bfd, buf);
- if (code_sec != NULL)
- {
- asection *sec;
-
- buf_likely = NULL;
- for (sec = opd_bfd->sections; sec != NULL; sec = sec->next)
- if (sec->vma <= buf_val
- && (sec->flags & SEC_LOAD) != 0
- && (sec->flags & SEC_ALLOC) != 0)
- buf_likely = sec;
- if (buf_likely != NULL)
- {
- *code_sec = buf_likely;
- if (code_off != NULL)
- *code_off = buf_val - buf_likely->vma;
+ {
+ asection *sec;
+
+ sec_search_done = TRUE;
+ last_code_sec = NULL;
+ for (sec = opd_bfd->sections; sec != NULL; sec = sec->next)
+ if (sec->vma <= last_entry_vma
+ && (sec->flags & SEC_LOAD) != 0
+ && (sec->flags & SEC_ALLOC) != 0)
+ last_code_sec = sec;
}
}
- else
- buf_likely = NULL;
- return buf_val;
+ if (code_sec != NULL && last_code_sec != NULL)
+ {
+ *code_sec = last_code_sec;
+ if (code_off != NULL)
+ *code_off = last_entry_vma - last_code_sec->vma;
+ }
+ return last_entry_vma;
}
BFD_ASSERT (is_ppc64_elf (opd_bfd));