This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch 3/5] [ppc64] PIE: Fix reprelinked attach
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Cc: Luis Machado <luisgpm at linux dot vnet dot ibm dot com>
- Date: Mon, 27 Sep 2010 21:01:25 +0200
- Subject: [patch 3/5] [ppc64] PIE: Fix reprelinked attach
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;
}