[patch 3/5] [ppc64] PIE: Fix reprelinked attach

Jan Kratochvil jan.kratochvil@redhat.com
Mon Sep 27 22:08:00 GMT 2010


Hi,

the PIE support does sanity checking if the process being `attach'ed matches
that of `exec_bfd'.  The PIE displacement determination could produce bogus
values otherwise.

Just sometimes (such as on ppc64 and also in some other linking
configurations) prelink can turn NOBITS .plt into PROGBITS .plt, modifying
also the DYNAMIC segment and failing the sanity check.

The duplication into 32bit and 64bit parts is getting ugly.  Just the current
GDB code generally makes the 32bit and 64bit code duplicate.

It fixes on ppc64 some of the *ATTACH break-interp.exp testcases.


Thanks,
Jan


gdb/
2010-09-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix attaching to re-prelinked executables on ppc64.
	* solib-svr4.c (svr4_exec_displacement): New variable plt2_asect,
	initialize it, try to adjust FILESZ field by it.

--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1844,6 +1844,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
 		  Elf32_External_Phdr *phdr2p;
 		  gdb_byte *buf_vaddr_p, *buf_paddr_p;
 		  CORE_ADDR vaddr, paddr;
+		  asection *plt2_asect;
 
 		  phdrp = &((Elf32_External_Phdr *) buf)[i];
 		  buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr;
@@ -1869,6 +1870,34 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
 		  if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
 		    continue;
 
+		  /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS.  */
+		  plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
+		  if (plt2_asect)
+		    {
+		      int content2;
+		      gdb_byte *buf_filesz_p = (gdb_byte *) &phdrp->p_filesz;
+		      CORE_ADDR filesz;
+
+		      content2 = (bfd_get_section_flags (exec_bfd, plt2_asect)
+				  & SEC_HAS_CONTENTS) != 0;
+
+		      filesz = extract_unsigned_integer (buf_filesz_p, 4,
+							 byte_order);
+
+		      /* PLT2_ASECT is from on-disk file (exec_bfd) while
+			 FILESZ is from the in-memory image.  */
+		      if (content2)
+			filesz += bfd_get_section_size (plt2_asect);
+		      else
+			filesz -= bfd_get_section_size (plt2_asect);
+
+		      store_unsigned_integer (buf_filesz_p, 4, byte_order,
+					      filesz);
+
+		      if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
+			continue;
+		    }
+
 		  ok = 0;
 		  break;
 		}
@@ -1921,6 +1950,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
 		  Elf64_External_Phdr *phdr2p;
 		  gdb_byte *buf_vaddr_p, *buf_paddr_p;
 		  CORE_ADDR vaddr, paddr;
+		  asection *plt2_asect;
 
 		  phdrp = &((Elf64_External_Phdr *) buf)[i];
 		  buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr;
@@ -1946,6 +1976,34 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
 		  if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
 		    continue;
 
+		  /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS.  */
+		  plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
+		  if (plt2_asect)
+		    {
+		      int content2;
+		      gdb_byte *buf_filesz_p = (gdb_byte *) &phdrp->p_filesz;
+		      CORE_ADDR filesz;
+
+		      content2 = (bfd_get_section_flags (exec_bfd, plt2_asect)
+				  & SEC_HAS_CONTENTS) != 0;
+
+		      filesz = extract_unsigned_integer (buf_filesz_p, 8,
+							 byte_order);
+
+		      /* PLT2_ASECT is from on-disk file (exec_bfd) while
+			 FILESZ is from the in-memory image.  */
+		      if (content2)
+			filesz += bfd_get_section_size (plt2_asect);
+		      else
+			filesz -= bfd_get_section_size (plt2_asect);
+
+		      store_unsigned_integer (buf_filesz_p, 8, byte_order,
+					      filesz);
+
+		      if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
+			continue;
+		    }
+
 		  ok = 0;
 		  break;
 		}



More information about the Gdb-patches mailing list