This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] [i386] Fix {,un}prelinked libraries for attach/core-load


Hi,

please see comments in the patch.  The adjusted testcase FAILs on i386.

"Prelink", March 4, 2004 - by Jakub Jelinek:
	http://people.redhat.com/jakub/prelink.pdf
	primarily section 7 - REL to RELA conversion

An example of unprelinked -> prelinked library change:
 Program Headers:
   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
-  LOAD           0x000000 0x00000000 0x00000000 0x00538 0x00538 R E 0x1000
-  LOAD           0x000538 0x00001538 0x00001538 0x00100 0x00110 RW  0x1000
-  DYNAMIC        0x000550 0x00001550 0x00001550 0x000c8 0x000c8 RW  0x4
-  NOTE           0x0000f4 0x000000f4 0x000000f4 0x00024 0x00024 R   0x4
-  GNU_EH_FRAME   0x0004e8 0x000004e8 0x000004e8 0x00014 0x00014 R   0x4
+  LOAD           0x000000 0x411b3000 0x411b3000 0x00558 0x00558 R E 0x1000
+  LOAD           0x000558 0x411b4558 0x411b4558 0x00100 0x00110 RW  0x1000
+  DYNAMIC        0x000570 0x411b4570 0x411b4570 0x000c8 0x000c8 RW  0x4
+  NOTE           0x0000f4 0x411b30f4 0x411b30f4 0x00024 0x00024 R   0x4
+  GNU_EH_FRAME   0x000508 0x411b3508 0x411b3508 0x00014 0x00014 R   0x4
   GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4

So far GDB expected all such displacements will be always PAGE_SIZE aligned.
This applies for example for re-prelinking of an already prelinked file.
But it does not apply for prelinking of an unprelinked file or unprelinking of
a prelinked file, there can be arbitrary displacement.

It affects i386 (=i686, prelink doc reports also ARM and MIPS) which uses REL.
x86_64 always uses RELA, therefore I have not noticed it so far.  i386 still
has to be supported.

This affects both attachment to a PID and core file loads.

This applies in real world if you transfer a core file between hosts and try to
backtrace them, libraries of both hosts may differ whether they are / are not
prelinked.

I could implement some (displacement-forgiving and prelink-modifications
forgiving) comparison of both DYNAMIC segments found.  But I do not think it is
useful, if the DYNAMIC address from linkmap vs. bfd do not match it is still a
better chance to try a displacement to make them match.  Keeping the file
relocation cannot work anyway when the DYNAMIC address is verified as wrong.

No regressions on {x86_64,x86_64-m32,i686}-fedora15-linux-gnu.

Mostly do you agree the DYNAMIC content does not have to be verifed?
Do you have any comments on the in-code long comments?


Thanks,
Jan


gdb/
2011-02-22  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix libraries displacement if they change whether they were prelinked.
	* solib-svr4.c (LM_ADDR_CHECK): Set L_ADDR even if the DYNAMIC pointer
	does not match.  Comment why.

gdb/testsuite/
2011-02-22  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/break-interp-lib.c (v, vptr): New variables.
	* gdb.base/break-interp.exp (test_attach): New comment.

--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -237,11 +237,11 @@ LM_ADDR_CHECK (struct so_list *so, bfd *abfd)
 
 	     Even on PPC it must be zero-aligned at least for MINPAGESIZE.  */
 
+	  l_addr = l_dynaddr - dynaddr;
+
 	  if ((l_addr & (minpagesize - 1)) == 0
 	      && (l_addr & align) == ((l_dynaddr - dynaddr) & align))
 	    {
-	      l_addr = l_dynaddr - dynaddr;
-
 	      if (info_verbose)
 		printf_unfiltered (_("Using PIC (Position Independent Code) "
 				     "prelink displacement %s for \"%s\".\n"),
@@ -249,9 +249,20 @@ LM_ADDR_CHECK (struct so_list *so, bfd *abfd)
 				   so->so_name);
 	    }
 	  else
-	    warning (_(".dynamic section for \"%s\" "
-		       "is not at the expected address "
-		       "(wrong library or version mismatch?)"), so->so_name);
+	    {
+	      /* There is no way to verify the library file matches.  prelink
+		 can during prelinking of an unprelinked file (or unprelinking
+		 of a prelinked file) shift the DYNAMIC segment by arbitrary
+		 offset without any page size alignment.  There is no way to
+		 find out the ELF header and/or Program Headers for a limited
+		 verification if it they match.  One could do a verification
+		 of the DYNAMIC segment.  Still the found address is the best
+		 one GDB could find.  */
+
+	      warning (_(".dynamic section for \"%s\" "
+			 "is not at the expected address "
+			 "(wrong library or version mismatch?)"), so->so_name);
+	    }
 	}
 
     set_addr:
--- a/gdb/testsuite/gdb.base/break-interp-lib.c
+++ b/gdb/testsuite/gdb.base/break-interp-lib.c
@@ -20,6 +20,10 @@
 #include <assert.h>
 #include <stdio.h>
 
+/* Force REL->RELA conversion on i386, see "Prelink", March 4, 2004.  */
+volatile int v[2];
+volatile int *vptr = &v[1];
+
 void
 libfunc (const char *action)
 {
--- a/gdb/testsuite/gdb.base/break-interp.exp
+++ b/gdb/testsuite/gdb.base/break-interp.exp
@@ -352,6 +352,14 @@ proc test_attach {file displacement {relink_args ""}} {
 	    # test simplicity, we merged this test and the test above by not
 	    # restoring $INTERP after $EXEC prelink.  $INTERP gets restored
 	    # later below.
+	    #
+	    # `(wrong library or version mismatch?)' messages are printed for
+	    # $binfile_lib on platforms converting REL->RELA relocations by
+	    # prelink (such as on i386).  There is no reliable way to verify
+	    # the library file matches the running library in such case but
+	    # GDB at least attempts to set the right displacement.  We test
+	    # `libfunc' is present in the backtrace and therefore the
+	    # displacement has been guessed right.
 
 	    if [prelink$relink $relink_args [file tail $exec]] {
 		# /proc/PID/exe cannot be loaded as it is "EXECNAME (deleted)".


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]