* ppc-linux-tdep.c (ppc64_linux_convert_from_func_ptr_addr): Read
authorUlrich Weigand <uweigand@de.ibm.com>
Thu, 21 Aug 2008 19:54:34 +0000 (19:54 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Thu, 21 Aug 2008 19:54:34 +0000 (19:54 +0000)
and manually relocate .opd contents from BFD instead of reading
them from target memory.

gdb/ChangeLog
gdb/ppc-linux-tdep.c

index 557ca044348da5e317b399f0ae8d59001b8ad04d..7cbefa3000b631a896934486c572e1cf59e89bdc 100644 (file)
@@ -1,3 +1,9 @@
+2008-08-21  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * 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.
+
 2008-08-21  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * dwarf2read.c (processing_current_prefix): Delete static
index ccf40855c7f7c11118167e0da9c981533ec6d845..c3c0c1b1d0c5a04f2b102b8afb2ec5a6a6d27f4f 100644 (file)
@@ -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;
 }