aboutsummaryrefslogtreecommitdiff
path: root/gdb/ppc-linux-tdep.c
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2008-08-21 19:54:34 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2008-08-21 19:54:34 +0000
commite84ee2403c3ad46833166512e5f16f189bec2dfd (patch)
treefc5835456fabad945b31dfaaa5f59a2528677eb6 /gdb/ppc-linux-tdep.c
parent8c9b70b1a5d4a033ce38d16981b31a1e2f67485d (diff)
downloadgdb-e84ee2403c3ad46833166512e5f16f189bec2dfd.zip
gdb-e84ee2403c3ad46833166512e5f16f189bec2dfd.tar.gz
gdb-e84ee2403c3ad46833166512e5f16f189bec2dfd.tar.bz2
* ppc-linux-tdep.c (ppc64_linux_convert_from_func_ptr_addr): Read
and manually relocate .opd contents from BFD instead of reading them from target memory.
Diffstat (limited to 'gdb/ppc-linux-tdep.c')
-rw-r--r--gdb/ppc-linux-tdep.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index ccf4085..c3c0c1b 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -604,7 +604,36 @@ ppc64_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
/* Check if ADDR points to a function descriptor. */
if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
- return get_target_memory_unsigned (targ, addr, 8);
+ {
+ /* There may be relocations that need to be applied to the .opd
+ section. Unfortunately, this function may be called at a time
+ where these relocations have not yet been performed -- this can
+ happen for example shortly after a library has been loaded with
+ dlopen, but ld.so has not yet applied the relocations.
+
+ To cope with both the case where the relocation has been applied,
+ and the case where it has not yet been applied, we do *not* read
+ the (maybe) relocated value from target memory, but we instead
+ read the non-relocated value from the BFD, and apply the relocation
+ offset manually.
+
+ This makes the assumption that all .opd entries are always relocated
+ by the same offset the section itself was relocated. This should
+ always be the case for GNU/Linux executables and shared libraries.
+ Note that other kind of object files (e.g. those added via
+ add-symbol-files) will currently never end up here anyway, as this
+ function accesses *target* sections only; only the main exec and
+ shared libraries are ever added to the target. */
+
+ gdb_byte buf[8];
+ int res;
+
+ res = bfd_get_section_contents (s->bfd, s->the_bfd_section,
+ &buf, addr - s->addr, 8);
+ if (res != 0)
+ return extract_unsigned_integer (buf, 8)
+ - bfd_section_vma (s->bfd, s->the_bfd_section) + s->addr;
+ }
return addr;
}