[rfa] Fix detection of prelinked libraries on PPC

Ulrich Weigand Ulrich.Weigand@de.ibm.com
Fri Jul 6 16:49:00 GMT 2007


Hello,

we've run into a problem detecting pre-linked libraries on PPC.
The situation is typically caused when debugging a core file or
remote target where the libaries used by the inferior differ
from those used by GDB, because they have been prelinked in
the meaning.

LM_ADDR_CHECK attempts to notice this situation, and distiguish
it from just random diffences due to different library versions
by the following check:

          /* If the changes match the alignment requirements, we
             assume we're using a core file that was generated by the
             same binary, just prelinked with a different base offset.
             If it doesn't match, we may have a different binary, the
             same binary with the dynamic table loaded at an unrelated
             location, or anything, really.  To avoid regressions,
             don't adjust the base offset in the latter case, although
             odds are that, if things really changed, debugging won't
             quite work.  */
          if ((l_addr & align) == 0 && ((dynaddr - l_dynaddr) & align) == 0)

This heuristic is based on the fact that prelink respects the
ELF section alignment requirements, and thus relocates the
library by a multiple of the maximum section alignment.

However, that test fails on PPC in some situations.  The PPC kernel
supports either 4k or 64k page sizes.  To be prepared for 64k pages,
PPC ELF files are built using an alignment requirement of 64k.  However,
when running on a kernel supporting 4k pages, the memory mapping of the
library may not actually happen on a 64k boundary!

Thus even the first test of the above condition, that the actual library
load address is a multiple of the alignment, may fail on PPC.


To make the heuristic work in that situation, I'm using the following
patch that simply tests that the relocation offset introduced by prelink
is a multiple of the alignment.

Note that l_addr - <prelink-relocation-offset> == l_dynaddr - dynaddr,
so that test can be simply written by checking that the adjusted base
offset (l_dynaddr - dynaddr) still has the same remainder (modulo the
aligment) as the original base offset l_addr:

  ((l_addr & align) == ((l_dynaddr - dynaddr) & align)

(In the usual case where (l_addr & align) == 0, this check is equivalent
to the original check.)

Tested on powerpc64-linux.   OK for mainline?

Bye,
Ulrich


ChangeLog:

	* solib-svr4.c (LM_ADDR_CHECK): Relax prelink recognition heuristic.

diff -urNp src-orig/gdb/solib-svr4.c src/gdb/solib-svr4.c
--- src-orig/gdb/solib-svr4.c	2007-06-25 21:38:36.871749134 +0200
+++ src/gdb/solib-svr4.c	2007-06-25 21:42:40.609768495 +0200
@@ -184,7 +184,7 @@ LM_ADDR_CHECK (struct so_list *so, bfd *
 	     don't adjust the base offset in the latter case, although
 	     odds are that, if things really changed, debugging won't
 	     quite work.  */
-	  if ((l_addr & align) == 0 && ((dynaddr - l_dynaddr) & align) == 0)
+	  if ((l_addr & align) == ((l_dynaddr - dynaddr) & align))
 	    {
 	      l_addr = l_dynaddr - dynaddr;
 
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com



More information about the Gdb-patches mailing list