This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[rfa] Fix detection of prelinked libraries on PPC
- From: Ulrich Weigand <Ulrich dot Weigand at de dot ibm dot com>
- To: <gdb-patches at sourceware dot org>
- Cc: kevinb at redhat dot com
- Date: Fri, 6 Jul 2007 18:49:42 +0200
- Subject: [rfa] Fix detection of prelinked libraries on PPC
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