Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH 1/3] Implement new Linux target vectors on BFD
@ 2013-01-30  6:53 Sergio Durigan Junior
  2013-01-30  9:16 ` Alan Modra
  0 siblings, 1 reply; 13+ messages in thread
From: Sergio Durigan Junior @ 2013-01-30  6:53 UTC (permalink / raw)
  To: Binutils Development; +Cc: GDB Patches, Pedro Alves, Jan Kratochvil, H. J. Lu

Hi all,

As a followup of my previous patch series, which can be found here:

<http://sourceware.org/ml/gdb-patches/2012-12/msg00534.html>
<http://sourceware.org/ml/gdb-patches/2012-12/msg00536.html>

...and (for this particular patch) as also a followup for Pedro's
comments on:

<http://sourceware.org/ml/gdb-patches/2013-01/msg00233.html>

I am sending this patch for appreciation and review.  It is the first
patch of the new PRPSINFO series, and all it does is basically:

1) Add new target vectors on the BFD configury system in order to handle
Linux targets, which will then make it possible to use certain functions
only on such targets, and

2) Hack the existing arch files on BFD (and one specifically on GDB) in
order to correctly declare and use these new targets.

I have chosen not to implement this to all architectures because for now
I only needed the ones which actually implemented the *_write_core_note
function, so you'll see that it touches basically ARM, i*86, x86_64, PPC
and PPC64.  As I mentioned above, I had to do modify a GDB file
(ppc-linux-tdep.c) because it declared its BFD target by hand.  Not a
big deal.

My first attempt to implement this (suggested by Pedro) was to actually
create a Linux-specific file (e.g., elf64-linux-x86-64.c) which would
#include the original implementation (elf64-x86-64.c in this example)
and extend it by reimplementing some functions.  In the end this
approach didn't work because of the way things are laid out in the
original file, so I started looking at the normal procedure for this.

I spent quite some time understanding how the BFD build system worked,
and how to actually hack it, so I hope I did not make any miserable
mistakes here.

Comments are welcome.

-- 
Sergio

bfd/ChangeLog:

2013-01-30  Sergio Durigan Junior  <sergiodj@redhat.com>

	* config.bfd: Add or modify ARM, i*86, x86_64, PPC and PPC64 targets
	for Linux kernel.
	* configure.in: Add *_vec definitions for ARM, i*86, x86_64, PPC and
	PPC64 targets for Linux kernel.
	* configure: Regenerate.
	* elf32-arm.c: Add support for Linux kernel.
	* elf32-i386.c: Likewise.
	* elf32-ppc.c: Likewise.
	* elf64-ppc.c: Likewise.
	* elf64-x86-64.c: Likewise.
	* targets.c (<bfd_elf32_bigarm_linux_vec>, <bfd_elf32_i386_linux_vec>,
	<bfd_elf32_littlearm_linux_vec>, <bfd_elf32_powerpc_linux_vec>,
	<bfd_elf32_powerpcle_linux_vec>, <bfd_elf64_powerpc_linux_vec>,
	<bfd_elf64_powerpcle_linux_vec>, <bfd_elf64_x86_64_linux_vec>,
	<bfd_elf32_x86_64_linux_vec>): New *_vec definitions for ARM, i*86,
	x86_64, PPC and PPC64 targets for Linux kernel.

gdb/ChangeLog:

2013-01-30  Sergio Durigan Junior  <sergiodj@redhat.com>

	* ppc-linux-tdep.c (ppc_linux_init_abi): Properly setting
	`gcore_bfd_target' with the Linux kernel variant.

---
 bfd/config.bfd       |   48 +++++++++++++++++++++++++++++++++++++-----------
 bfd/configure        |   11 ++++++++++-
 bfd/configure.in     |   11 ++++++++++-
 bfd/elf32-arm.c      |   15 +++++++++++++++
 bfd/elf32-i386.c     |   11 +++++++++++
 bfd/elf32-ppc.c      |   15 +++++++++++++++
 bfd/elf64-ppc.c      |   15 +++++++++++++++
 bfd/elf64-x86-64.c   |   31 +++++++++++++++++++++++++++++++
 bfd/targets.c        |   18 ++++++++++++++++++
 gdb/ppc-linux-tdep.c |    8 ++++----
 11 files changed, 167 insertions(+), 18 deletions(-)

diff --git a/bfd/config.bfd b/bfd/config.bfd
index cd19936..d2d9c32 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -322,20 +322,28 @@ case "${targ}" in
     targ_defvec=bfd_elf32_littlearm_vec
     targ_selvecs=bfd_elf32_bigarm_vec
     ;;
-  armeb-*-elf | arm*b-*-linux-*)
+  armeb-*-elf)
     targ_defvec=bfd_elf32_bigarm_vec
     targ_selvecs=bfd_elf32_littlearm_vec
     ;;
+  arm*b-*-linux-*)
+    targ_defvec=bfd_elf32_bigarm_linux_vec
+    targ_selvecs=bfd_elf32_littlearm_linux_vec
+    ;;
   arm-*-kaos*)
     targ_defvec=bfd_elf32_littlearm_vec
     targ_selvecs=bfd_elf32_bigarm_vec
     ;;
-  arm-*-elf | arm-*-freebsd* | arm*-*-linux-* | arm*-*-conix* | \
+  arm-*-elf | arm-*-freebsd* | arm*-*-conix* | \
   arm*-*-uclinux* | arm-*-kfreebsd*-gnu | \
   arm*-*-eabi* )
     targ_defvec=bfd_elf32_littlearm_vec
     targ_selvecs=bfd_elf32_bigarm_vec
     ;;
+  arm*-*-linux-*)
+    targ_defvec=bfd_elf32_littlearm_linux_vec
+    targ_selvecs=bfd_elf32_bigarm_linux_vec
+    ;;
   arm*-*-vxworks | arm*-*-windiss)
     targ_defvec=bfd_elf32_littlearm_vxworks_vec
     targ_selvecs=bfd_elf32_bigarm_vxworks_vec
@@ -619,9 +627,9 @@ case "${targ}" in
     targ_underscore=yes
     ;;
   i[3-7]86-*-linux-*)
-    targ_defvec=bfd_elf32_i386_vec
+    targ_defvec=bfd_elf32_i386_linux_vec
     targ_selvecs="i386linux_vec i386pei_vec"
-    targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf32_x86_64_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec"
+    targ64_selvecs="bfd_elf64_x86_64_linux_vec bfd_elf32_x86_64_linux_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec"
     ;;
   i[3-7]86-*-nacl*)
     targ_defvec=bfd_elf32_i386_nacl_vec
@@ -662,8 +670,8 @@ case "${targ}" in
     want64=true
     ;;
   x86_64-*-linux-*)
-    targ_defvec=bfd_elf64_x86_64_vec
-    targ_selvecs="bfd_elf32_i386_vec bfd_elf32_x86_64_vec i386linux_vec i386pei_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec"
+    targ_defvec=bfd_elf64_x86_64_linux_vec
+    targ_selvecs="bfd_elf32_i386_linux_vec bfd_elf32_x86_64_linux_vec i386linux_vec i386pei_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec"
     want64=true
     ;;
   x86_64-*-nacl*)
@@ -1220,17 +1228,26 @@ case "${targ}" in
     targ_selvecs="bfd_elf64_powerpc_vec bfd_elf32_powerpc_vec bfd_elf32_powerpc_freebsd_vec bfd_elf32_powerpcle_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec"
     want64=true
     ;;
-  powerpc64-*-elf* | powerpc-*-elf64* | powerpc64-*-linux* | \
-  powerpc64-*-*bsd*)
+  powerpc64-*-elf* | powerpc-*-elf64* | powerpc64-*-*bsd*)
     targ_defvec=bfd_elf64_powerpc_vec
     targ_selvecs="bfd_elf64_powerpcle_vec bfd_elf32_powerpc_vec bfd_elf32_powerpcle_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec"
     want64=true
     ;;
+  powerpc64-*-linux*)
+    targ_defvec=bfd_elf64_powerpc_linux_vec
+    targ_selvecs="bfd_elf64_powerpcle_linux_vec bfd_elf32_powerpc_linux_vec bfd_elf32_powerpcle_linux_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec"
+    want64=true
+    ;;
   powerpc64le-*-elf* | powerpcle-*-elf64*)
     targ_defvec=bfd_elf64_powerpcle_vec
     targ_selvecs="bfd_elf64_powerpc_vec bfd_elf32_powerpcle_vec bfd_elf32_powerpc_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec"
     want64=true
     ;;
+  powerpc64le-*-linux*)
+    targ_defvec=bfd_elf64_powerpcle_linux_vec
+    targ_selvecs="bfd_elf64_powerpc_linux_vec bfd_elf32_powerpcle_linux_vec bfd_elf32_powerpc_linux_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec"
+    want64=true
+    ;;
 #endif
   powerpc-*-*freebsd*)
     targ_defvec=bfd_elf32_powerpc_freebsd_vec
@@ -1238,12 +1255,16 @@ case "${targ}" in
     targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec bfd_elf64_powerpc_freebsd_vec"
     ;;
   powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \
-  powerpc-*-solaris2* | powerpc-*-linux-* | powerpc-*-rtems* | \
-  powerpc-*-chorus*)
+  powerpc-*-solaris2* | powerpc-*-rtems* | powerpc-*-chorus*)
     targ_defvec=bfd_elf32_powerpc_vec
     targ_selvecs="rs6000coff_vec bfd_elf32_powerpcle_vec ppcboot_vec"
     targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec"
     ;;
+  powerpc-*-linux-*)
+    targ_defvec=bfd_elf32_powerpc_linux_vec
+    targ_selvecs="rs6000coff_vec bfd_elf32_powerpcle_linux_vec ppcboot_vec"
+    targ64_selvecs="bfd_elf64_powerpc_linux_vec bfd_elf64_powerpcle_linux_vec"
+    ;;
   powerpc-*-kaos*)
     targ_defvec=bfd_elf32_powerpc_vec
     targ_selvecs="bfd_elf32_powerpcle_vec ppcboot_vec"
@@ -1280,11 +1301,16 @@ case "${targ}" in
     targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec ppcboot_vec"
     ;;
   powerpcle-*-elf* | powerpcle-*-sysv4* | powerpcle-*-eabi* | \
-  powerpcle-*-solaris2* | powerpcle-*-linux-* | powerpcle-*-vxworks*)
+  powerpcle-*-solaris2* | powerpcle-*-vxworks*)
     targ_defvec=bfd_elf32_powerpcle_vec
     targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec ppcboot_vec"
     targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec"
     ;;
+  powerpcle-*-linux-*)
+    targ_defvec=bfd_elf32_powerpcle_linux_vec
+    targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_linux_vec ppcboot_vec"
+    targ64_selvecs="bfd_elf64_powerpc_linux_vec bfd_elf64_powerpcle_linux_vec"
+    ;;
   powerpcle-*-pe | powerpcle-*-winnt* | powerpcle-*-cygwin*)
     targ_defvec=bfd_powerpcle_pe_vec
     targ_selvecs="bfd_powerpcle_pei_vec bfd_powerpc_pei_vec bfd_powerpcle_pe_vec bfd_powerpc_pe_vec"
diff --git a/bfd/configure b/bfd/configure
index 1279e56..31a7915 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -15219,6 +15219,7 @@ do
     bfd_elf32_big_generic_vec) 	tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_bigarc_vec)	tb="$tb elf32-arc.lo elf32.lo $elf" ;;
     bfd_elf32_bigarm_vec)	tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    bfd_elf32_bigarm_linux_vec)	tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigarm_nacl_vec)	tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigarm_symbian_vec)
                                 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
@@ -15249,6 +15250,7 @@ do
     bfd_elf32_i386_nacl_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vxworks_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_linux_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i860_little_vec)	tb="$tb elf32-i860.lo elf32.lo $elf" ;;
     bfd_elf32_i860_vec)		tb="$tb elf32-i860.lo elf32.lo $elf" ;;
     bfd_elf32_i960_vec)		tb="$tb elf32-i960.lo elf32.lo $elf" ;;
@@ -15265,6 +15267,7 @@ do
     bfd_elf32_littlearm_vxworks_vec)
                                 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlearm_vec)	tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    bfd_elf32_littlearm_linux_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlearm_nacl_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlemips_vec) 	tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_littlemips_vxworks_vec)
@@ -15301,7 +15304,9 @@ do
     bfd_elf32_pj_vec)           tb="$tb elf32-pj.lo elf32.lo $elf";;
     bfd_elf32_pjl_vec)          tb="$tb elf32-pj.lo elf32.lo $elf";;
     bfd_elf32_powerpc_vec)	tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_powerpc_linux_vec)tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_powerpcle_vec)	tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_powerpcle_linux_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_powerpc_freebsd_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_powerpc_vxworks_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_rl78_vec)         tb="$tb elf32-rl78.lo $elf" ;;
@@ -15373,7 +15378,9 @@ do
     bfd_elf64_littlemips_vec) 	tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_mmix_vec) 	tb="$tb elf64-mmix.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_powerpc_vec)	tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf64_powerpcle_vec)	tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
+    bfd_elf64_powerpc_linux_vec)tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_powerpcle_vec)	tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_powerpcle_linux_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_powerpc_freebsd_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_s390_vec)		tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_sh64_vec)		tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
@@ -15395,7 +15402,9 @@ do
     bfd_elf64_x86_64_nacl_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_x86_64_sol2_vec)  tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_x86_64_linux_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf32_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
+    bfd_elf32_x86_64_linux_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
     bfd_elf32_x86_64_nacl_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
     bfd_elf64_l1om_vec)		tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_l1om_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
diff --git a/bfd/configure.in b/bfd/configure.in
index 33f62e3..94651cd 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -716,6 +716,7 @@ do
     bfd_elf32_big_generic_vec) 	tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_bigarc_vec)	tb="$tb elf32-arc.lo elf32.lo $elf" ;;
     bfd_elf32_bigarm_vec)	tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    bfd_elf32_bigarm_linux_vec)	tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigarm_nacl_vec)	tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigarm_symbian_vec)
                                 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
@@ -746,6 +747,7 @@ do
     bfd_elf32_i386_nacl_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vxworks_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_linux_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i860_little_vec)	tb="$tb elf32-i860.lo elf32.lo $elf" ;;
     bfd_elf32_i860_vec)		tb="$tb elf32-i860.lo elf32.lo $elf" ;;
     bfd_elf32_i960_vec)		tb="$tb elf32-i960.lo elf32.lo $elf" ;;
@@ -762,6 +764,7 @@ do
     bfd_elf32_littlearm_vxworks_vec)
                                 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlearm_vec)	tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    bfd_elf32_littlearm_linux_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlearm_nacl_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlemips_vec) 	tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_littlemips_vxworks_vec)
@@ -798,7 +801,9 @@ do
     bfd_elf32_pj_vec)           tb="$tb elf32-pj.lo elf32.lo $elf";;
     bfd_elf32_pjl_vec)          tb="$tb elf32-pj.lo elf32.lo $elf";;
     bfd_elf32_powerpc_vec)	tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_powerpc_linux_vec)tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_powerpcle_vec)	tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_powerpcle_linux_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_powerpc_freebsd_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_powerpc_vxworks_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_rl78_vec)         tb="$tb elf32-rl78.lo $elf" ;;
@@ -870,7 +875,9 @@ do
     bfd_elf64_littlemips_vec) 	tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_mmix_vec) 	tb="$tb elf64-mmix.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_powerpc_vec)	tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf64_powerpcle_vec)	tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
+    bfd_elf64_powerpc_linux_vec)tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_powerpcle_vec)	tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_powerpcle_linux_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_powerpc_freebsd_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_s390_vec)		tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_sh64_vec)		tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
@@ -892,7 +899,9 @@ do
     bfd_elf64_x86_64_nacl_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_x86_64_sol2_vec)  tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_x86_64_linux_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf32_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
+    bfd_elf32_x86_64_linux_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
     bfd_elf32_x86_64_nacl_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
     bfd_elf64_l1om_vec)		tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_l1om_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index e2f8a96..4dfd113 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -15732,6 +15732,21 @@ const struct elf_size_info elf32_arm_size_info =
 
 #include "elf32-target.h"
 
+/* ARM support on Linux kernel.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM               bfd_elf32_littlearm_linux_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME              "elf32-littlearm-linux"
+#undef  TARGET_BIG_SYM
+#define TARGET_BIG_SYM                  bfd_elf32_bigarm_linux_vec
+#undef  TARGET_BIG_NAME
+#define TARGET_BIG_NAME                 "elf32-bigarm-linux"
+#undef  elf32_bed
+#define	elf32_bed			elf32_arm_linux_bed
+
+#include "elf32-target.h"
+
 /* Native Client targets.  */
 
 #undef	TARGET_LITTLE_SYM
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 01e50a4..5ef518e 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -5104,6 +5104,17 @@ elf_i386_add_symbol_hook (bfd * abfd,
 
 #include "elf32-target.h"
 
+/* i386 on Linux.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM		bfd_elf32_i386_linux_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME		"elf32-i386-linux"
+#undef  elf32_bed
+#define	elf32_bed			elf32_i386_linux_bed
+
+#include "elf32-target.h"
+
 /* FreeBSD support.  */
 
 #undef	TARGET_LITTLE_SYM
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 3f4e4bf..1272b5a 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -9806,6 +9806,21 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
 
 #include "elf32-target.h"
 
+/* PowerPC on Linux.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM		bfd_elf32_powerpcle_linux_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME		"elf32-powerpcle-linux"
+#undef  TARGET_BIG_SYM
+#define TARGET_BIG_SYM			bfd_elf32_powerpc_linux_vec
+#undef  TARGET_BIG_NAME
+#define TARGET_BIG_NAME			"elf32-powerpc-linux"
+#undef  elf32_bed
+#define elf32_bed			elf32_powerpc_linux_bed
+
+#include "elf32-target.h"
+
 /* FreeBSD Target */
 
 #undef  TARGET_LITTLE_SYM
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 2f6999b..e4e9d44 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -14261,6 +14261,21 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
 
 #include "elf64-target.h"
 
+/* PowerPC64 support on Linux.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM	      bfd_elf64_powerpcle_linux_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME	      "elf64-powerpcle-linux"
+#undef  TARGET_BIG_SYM
+#define TARGET_BIG_SYM		      bfd_elf64_powerpc_linux_vec
+#undef  TARGET_BIG_NAME
+#define TARGET_BIG_NAME		      "elf64-powerpc-linux"
+#undef  elf64_bed
+#define elf64_bed		      elf64_powerpc_linux_bed
+
+#include "elf64-target.h"
+
 /* FreeBSD support */
 
 #undef  TARGET_LITTLE_SYM
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 71f33e2..04d46a8 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -5259,6 +5259,18 @@ static const struct bfd_elf_special_section
 
 #include "elf64-target.h"
 
+/* x86_64 on Linux kernel.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM		bfd_elf64_x86_64_linux_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME		"el64-x86-64-linux"
+
+#undef  elf64_bed
+#define elf64_bed			elf64_x86_64_linux_bed
+
+#include "elf64-target.h"
+
 /* FreeBSD support.  */
 
 #undef  TARGET_LITTLE_SYM
@@ -5592,6 +5604,25 @@ elf64_k1om_elf_object_p (bfd *abfd)
 
 #include "elf64-target.h"
 
+/* 32bit x86-64 Linux support.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM		    bfd_elf32_x86_64_linux_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME		    "elf32-x86-64-linux"
+#undef	elf32_bed
+#define elf32_bed			    elf32_x86_64_linux_bed
+
+#undef ELF_ARCH
+#define ELF_ARCH			    bfd_arch_i386
+
+#undef	ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE		    EM_X86_64
+
+#undef	ELF_OSABI
+
+#include "elf32-target.h"
+
 /* 32bit x86-64 support.  */
 
 #undef  TARGET_LITTLE_SYM
diff --git a/bfd/targets.c b/bfd/targets.c
index 17553eb..2a73343 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -601,6 +601,7 @@ extern const bfd_target bfd_elf32_bfinfdpic_vec;
 extern const bfd_target bfd_elf32_big_generic_vec;
 extern const bfd_target bfd_elf32_bigarc_vec;
 extern const bfd_target bfd_elf32_bigarm_vec;
+extern const bfd_target bfd_elf32_bigarm_linux_vec;
 extern const bfd_target bfd_elf32_bigarm_nacl_vec;
 extern const bfd_target bfd_elf32_bigarm_symbian_vec;
 extern const bfd_target bfd_elf32_bigarm_vxworks_vec;
@@ -628,6 +629,7 @@ extern const bfd_target bfd_elf32_i386_nacl_vec;
 extern const bfd_target bfd_elf32_i386_sol2_vec;
 extern const bfd_target bfd_elf32_i386_vxworks_vec;
 extern const bfd_target bfd_elf32_i386_vec;
+extern const bfd_target bfd_elf32_i386_linux_vec;
 extern const bfd_target bfd_elf32_i860_little_vec;
 extern const bfd_target bfd_elf32_i860_vec;
 extern const bfd_target bfd_elf32_i960_vec;
@@ -640,6 +642,7 @@ extern const bfd_target bfd_elf32_lm32fdpic_vec;
 extern const bfd_target bfd_elf32_little_generic_vec;
 extern const bfd_target bfd_elf32_littlearc_vec;
 extern const bfd_target bfd_elf32_littlearm_vec;
+extern const bfd_target bfd_elf32_littlearm_linux_vec;
 extern const bfd_target bfd_elf32_littlearm_nacl_vec;
 extern const bfd_target bfd_elf32_littlearm_symbian_vec;
 extern const bfd_target bfd_elf32_littlearm_vxworks_vec;
@@ -677,7 +680,9 @@ extern const bfd_target bfd_elf32_or32_big_vec;
 extern const bfd_target bfd_elf32_pj_vec;
 extern const bfd_target bfd_elf32_pjl_vec;
 extern const bfd_target bfd_elf32_powerpc_vec;
+extern const bfd_target bfd_elf32_powerpc_linux_vec;
 extern const bfd_target bfd_elf32_powerpcle_vec;
+extern const bfd_target bfd_elf32_powerpcle_linux_vec;
 extern const bfd_target bfd_elf32_powerpc_freebsd_vec;
 extern const bfd_target bfd_elf32_powerpc_vxworks_vec;
 extern const bfd_target bfd_elf32_rl78_vec;
@@ -746,7 +751,9 @@ extern const bfd_target bfd_elf64_littlemips_vec;
 extern const bfd_target bfd_elf64_littleaarch64_vec;
 extern const bfd_target bfd_elf64_mmix_vec;
 extern const bfd_target bfd_elf64_powerpc_vec;
+extern const bfd_target bfd_elf64_powerpc_linux_vec;
 extern const bfd_target bfd_elf64_powerpcle_vec;
+extern const bfd_target bfd_elf64_powerpcle_linux_vec;
 extern const bfd_target bfd_elf64_powerpc_freebsd_vec;
 extern const bfd_target bfd_elf64_s390_vec;
 extern const bfd_target bfd_elf64_sh64_vec;
@@ -768,8 +775,10 @@ extern const bfd_target bfd_elf64_x86_64_freebsd_vec;
 extern const bfd_target bfd_elf64_x86_64_nacl_vec;
 extern const bfd_target bfd_elf64_x86_64_sol2_vec;
 extern const bfd_target bfd_elf64_x86_64_vec;
+extern const bfd_target bfd_elf64_x86_64_linux_vec;
 extern const bfd_target bfd_elf32_x86_64_nacl_vec;
 extern const bfd_target bfd_elf32_x86_64_vec;
+extern const bfd_target bfd_elf32_x86_64_linux_vec;
 extern const bfd_target bfd_elf64_l1om_freebsd_vec;
 extern const bfd_target bfd_elf64_l1om_vec;
 extern const bfd_target bfd_elf64_k1om_freebsd_vec;
@@ -979,6 +988,7 @@ static const bfd_target * const _bfd_target_vector[] =
 	&bfd_elf32_big_generic_vec,
 	&bfd_elf32_bigarc_vec,
 	&bfd_elf32_bigarm_vec,
+	&bfd_elf32_bigarm_linux_vec,
 	&bfd_elf32_bigarm_symbian_vec,
 	&bfd_elf32_bigarm_vxworks_vec,
 	&bfd_elf32_bigmips_vec,
@@ -1005,6 +1015,7 @@ static const bfd_target * const _bfd_target_vector[] =
 	&bfd_elf32_i386_sol2_vec,
 	&bfd_elf32_i386_vxworks_vec,
 	&bfd_elf32_i386_vec,
+	&bfd_elf32_i386_linux_vec,
 	&bfd_elf32_i860_little_vec,
 	&bfd_elf32_i860_vec,
 	&bfd_elf32_i960_vec,
@@ -1020,6 +1031,7 @@ static const bfd_target * const _bfd_target_vector[] =
 	&bfd_elf32_little_generic_vec,
 	&bfd_elf32_littlearc_vec,
 	&bfd_elf32_littlearm_vec,
+	&bfd_elf32_littlearm_linux_vec,
 	&bfd_elf32_littlearm_symbian_vec,
 	&bfd_elf32_littlearm_vxworks_vec,
 	&bfd_elf32_littlemips_vec,
@@ -1056,8 +1068,10 @@ static const bfd_target * const _bfd_target_vector[] =
 	&bfd_elf32_pj_vec,
 	&bfd_elf32_pjl_vec,
 	&bfd_elf32_powerpc_vec,
+	&bfd_elf32_powerpc_linux_vec,
 	&bfd_elf32_powerpc_vxworks_vec,
 	&bfd_elf32_powerpcle_vec,
+	&bfd_elf32_powerpcle_linux_vec,
 	&bfd_elf32_powerpc_freebsd_vec,
 	&bfd_elf32_rl78_vec,
 	&bfd_elf32_rx_be_vec,
@@ -1126,7 +1140,9 @@ static const bfd_target * const _bfd_target_vector[] =
 	&bfd_elf64_littleaarch64_vec,
 	&bfd_elf64_mmix_vec,
 	&bfd_elf64_powerpc_vec,
+	&bfd_elf64_powerpc_linux_vec,
 	&bfd_elf64_powerpcle_vec,
+	&bfd_elf64_powerpcle_linux_vec,
 	&bfd_elf64_powerpc_freebsd_vec,
 	&bfd_elf64_s390_vec,
 	&bfd_elf64_sh64_vec,
@@ -1148,8 +1164,10 @@ static const bfd_target * const _bfd_target_vector[] =
 	&bfd_elf64_x86_64_nacl_vec,
 	&bfd_elf64_x86_64_sol2_vec,
 	&bfd_elf64_x86_64_vec,
+	&bfd_elf64_x86_64_linux_vec,
 	&bfd_elf32_x86_64_nacl_vec,
 	&bfd_elf32_x86_64_vec,
+	&bfd_elf32_x86_64_linux_vec,
 	&bfd_elf64_l1om_freebsd_vec,
 	&bfd_elf64_l1om_vec,
 	&bfd_elf64_k1om_freebsd_vec,
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 135dc75..6cf089c 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -1708,9 +1708,9 @@ ppc_linux_init_abi (struct gdbarch_info info,
 
       /* BFD target for core files.  */
       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
-	set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpcle");
+	set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpcle-linux");
       else
-	set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
+	set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc-linux");
 
       /* Supported register sections.  */
       if (tdesc_find_feature (info.target_desc,
@@ -1760,9 +1760,9 @@ ppc_linux_init_abi (struct gdbarch_info info,
 
       /* BFD target for core files.  */
       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
-	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpcle");
+	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpcle-linux");
       else
-	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
+	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc-linux");
 
       /* Supported register sections.  */
       if (tdesc_find_feature (info.target_desc,
-- 
1.7.7.6


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Implement new Linux target vectors on BFD
  2013-01-30  6:53 [PATCH 1/3] Implement new Linux target vectors on BFD Sergio Durigan Junior
@ 2013-01-30  9:16 ` Alan Modra
  2013-01-30 16:43   ` Sergio Durigan Junior
  2013-01-30 16:44   ` [PATCH 1/3] Implement new Linux target vectors on BFD H.J. Lu
  0 siblings, 2 replies; 13+ messages in thread
From: Alan Modra @ 2013-01-30  9:16 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Binutils Development, GDB Patches, Pedro Alves, Jan Kratochvil, H. J. Lu

On Wed, Jan 30, 2013 at 04:52:46AM -0200, Sergio Durigan Junior wrote:
> 1) Add new target vectors on the BFD configury system in order to handle
> Linux targets, which will then make it possible to use certain functions
> only on such targets, and

Duplicating targets isn't a really good idea.

If on my x86_64 linux box I want to build a native binutils that also
supports powerpc64, I can configure binutils with
--enable-targets=powerpc64-linux, or get all targets with
--enable-targets=all.  The problem with adding bfd targets as you've
done is that now you have two bfd targets that give equally good
matches for powerpc64 objects.  So instead of one "best" match we now
have two.  elf64-big will also match, and by a quirk of the way
bfd_check_format_matches operates (giving priority to targets
appearing in config.bfd targ_selvec), this match will be chosen over
the better elf64-powerpc-* matches.  That means a worse user
experience for say, "objdump -d".  A file that used to happily
disassemble now gives you

some_file:     file format elf64-big

binutils/objdump: can't disassemble for architecture UNKNOWN!

You may have noticed that we've already made a mess of targets for
ARM, i386, x86_64 and powerpc.  I'd rather not see the same happen for
powerpc64 without a really good reason.

-- 
Alan Modra
Australia Development Lab, IBM


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Implement new Linux target vectors on BFD
  2013-01-30  9:16 ` Alan Modra
@ 2013-01-30 16:43   ` Sergio Durigan Junior
  2013-01-31 17:19     ` Pedro Alves
  2013-01-30 16:44   ` [PATCH 1/3] Implement new Linux target vectors on BFD H.J. Lu
  1 sibling, 1 reply; 13+ messages in thread
From: Sergio Durigan Junior @ 2013-01-30 16:43 UTC (permalink / raw)
  To: Binutils Development; +Cc: GDB Patches, Pedro Alves, Jan Kratochvil, H. J. Lu

On Wednesday, January 30 2013, Alan Modra wrote:

> On Wed, Jan 30, 2013 at 04:52:46AM -0200, Sergio Durigan Junior wrote:
>> 1) Add new target vectors on the BFD configury system in order to handle
>> Linux targets, which will then make it possible to use certain functions
>> only on such targets, and
>
> Duplicating targets isn't a really good idea.
>
> If on my x86_64 linux box I want to build a native binutils that also
> supports powerpc64, I can configure binutils with
> --enable-targets=powerpc64-linux, or get all targets with
> --enable-targets=all.  The problem with adding bfd targets as you've
> done is that now you have two bfd targets that give equally good
> matches for powerpc64 objects.  So instead of one "best" match we now
> have two.  elf64-big will also match, and by a quirk of the way
> bfd_check_format_matches operates (giving priority to targets
> appearing in config.bfd targ_selvec), this match will be chosen over
> the better elf64-powerpc-* matches.  That means a worse user
> experience for say, "objdump -d".  A file that used to happily
> disassemble now gives you
>
> some_file:     file format elf64-big
>
> binutils/objdump: can't disassemble for architecture UNKNOWN!

Hm, thank you for the explanation, it didn't occurred to me.

> You may have noticed that we've already made a mess of targets for
> ARM, i386, x86_64 and powerpc.  I'd rather not see the same happen for
> powerpc64 without a really good reason.

Right.  Now I am stuck with this, then.  While Pedro wants this feature
to be Linux-specific, now there is this problem with target duplication.

I will look for other solutions here, but if you alreay have some idea
on how to handle it, I'd be glad to read.

Thanks a lot,

-- 
Sergio


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Implement new Linux target vectors on BFD
  2013-01-30  9:16 ` Alan Modra
  2013-01-30 16:43   ` Sergio Durigan Junior
@ 2013-01-30 16:44   ` H.J. Lu
  1 sibling, 0 replies; 13+ messages in thread
From: H.J. Lu @ 2013-01-30 16:44 UTC (permalink / raw)
  To: Sergio Durigan Junior, Binutils Development, GDB Patches,
	Pedro Alves, Jan Kratochvil, H. J. Lu

On Wed, Jan 30, 2013 at 1:16 AM, Alan Modra <amodra@gmail.com> wrote:
> On Wed, Jan 30, 2013 at 04:52:46AM -0200, Sergio Durigan Junior wrote:
>> 1) Add new target vectors on the BFD configury system in order to handle
>> Linux targets, which will then make it possible to use certain functions
>> only on such targets, and
>
> Duplicating targets isn't a really good idea.
>
> If on my x86_64 linux box I want to build a native binutils that also
> supports powerpc64, I can configure binutils with
> --enable-targets=powerpc64-linux, or get all targets with
> --enable-targets=all.  The problem with adding bfd targets as you've
> done is that now you have two bfd targets that give equally good
> matches for powerpc64 objects.  So instead of one "best" match we now
> have two.  elf64-big will also match, and by a quirk of the way
> bfd_check_format_matches operates (giving priority to targets
> appearing in config.bfd targ_selvec), this match will be chosen over
> the better elf64-powerpc-* matches.  That means a worse user
> experience for say, "objdump -d".  A file that used to happily
> disassemble now gives you
>
> some_file:     file format elf64-big
>
> binutils/objdump: can't disassemble for architecture UNKNOWN!
>
> You may have noticed that we've already made a mess of targets for
> ARM, i386, x86_64 and powerpc.  I'd rather not see the same happen for
> powerpc64 without a really good reason.
>

I agree with Alan.  I don't want x86 Linux BFD targets.  Please
find another solution.

-- 
H.J.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Implement new Linux target vectors on BFD
  2013-01-30 16:43   ` Sergio Durigan Junior
@ 2013-01-31 17:19     ` Pedro Alves
  2013-01-31 23:04       ` [PATCH 1/2] New entry points for writing Linux NT_PRPSINFO notes Pedro Alves
  2013-01-31 23:05       ` [PATCH 2/2] Put more info in NT_PRPSINFO Linux notes Pedro Alves
  0 siblings, 2 replies; 13+ messages in thread
From: Pedro Alves @ 2013-01-31 17:19 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Binutils Development, GDB Patches, Jan Kratochvil, H. J. Lu

On 01/30/2013 04:42 PM, Sergio Durigan Junior wrote:
> On Wednesday, January 30 2013, Alan Modra wrote:

>> Duplicating targets isn't a really good idea.

> Hm, thank you for the explanation, it didn't occurred to me.

Indeed.  Thanks.

>> You may have noticed that we've already made a mess of targets for
>> ARM, i386, x86_64 and powerpc.  I'd rather not see the same happen for
>> powerpc64 without a really good reason.
>
> Right.  Now I am stuck with this, then.  While Pedro wants this feature
> to be Linux-specific, now there is this problem with target
> duplication.

It's not about what I want.  It's about the fact that different
targets/OSs have different prpsinfo etc. structures.

> I will look for other solutions here, but if you alreay have some idea
> on how to handle it, I'd be glad to read.

My idea is to cut the middle man.  AFAICS, only GDB wants to generate
core files presently.  GDB has a whole OS/arch sniffer mechanism in
place, where we know which target/arch/OS it is that is being
debugged.  So rather than having bfd know which prpsinfo layout we
want, and shoehorn different elf_internal_prpsinfo & friends
structures through the elfcore_write_note/va_args generic interface,
skip the bfd vector, and add new entry points in bfd for each possible
output, and have GDB pick the one it needs.  Since most Linux archs
have the same prpsinfo32 and prpsinfo64 layout, we just put the
default Linux implementations in elf.c.  PPC32, being the odd one out,
gets its own implementation.  I'll send updated bfd and gdb patches
as response to this email.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/2] New entry points for writing Linux NT_PRPSINFO notes.
  2013-01-31 17:19     ` Pedro Alves
@ 2013-01-31 23:04       ` Pedro Alves
  2013-02-01  6:37         ` Alan Modra
  2013-01-31 23:05       ` [PATCH 2/2] Put more info in NT_PRPSINFO Linux notes Pedro Alves
  1 sibling, 1 reply; 13+ messages in thread
From: Pedro Alves @ 2013-01-31 23:04 UTC (permalink / raw)
  To: binutils; +Cc: jan.kratochvil, hongjiu.lu, gdb-patches, sergiodj

GDB wants to be able to write more complete NT_PRPSINFO Linux notes in
core files.  Currently only a few fields are filled in -- fname,
psargs.  The current interface, elfcore_write_note is va_args based.
This gets ugly and hard to manage when you expand from those 2 args to
many more.  Another point we'd like to address is that core generation
should be host independent, and not depend on the default configured
target.  IOW, with GDB on host X, connected to a GDBserver running on
host Y, we want the gcore command to generate correct cores for Y, not
X.  This should be true even if neither X nor Y are the default target
for that bfd/GDB build (e.g., a --target=Z --enable-targets=all
build).

One complication is that different kernels/core ABIs have different
prpsinfo_t (and prstatus_t, etc.) structures.  Since almost duplicate
bfd target vectors for an arch is not desirable (say, one bare metal,
one Solaris, one GNU/Linux, all for the same arch), one solution would
be to make each write_core_note hooks themselves know for which OS
they are generating the core for.  To know which OS it is, I could
picture things like looking at elf_elfheader (abfd)->e_ident[EI_OSABI]
and other possible identifying bits in the bfd.  I think that'd get
ugly fast, introduces core generation ordering issues, and, well, GDB
already has the necessary info handy (for core reading, GDB does look
at EI_OSABI and other identifying bits in its osabi "sniff"ing
machinery, but also queries the running target, and other non-bfd
bits).

Since GDB has the needed info already, I believe the simplest solution
to all this, is the one below.

Add a new "struct elf_internal_linux_prpsinfo" structure that is the
internal representation of Linux prpsinfo.  The Linux-speficic (but
host-independent) bits of GDB that drive bfd into generating core
notes will instanciate an object of this type, fill it in, and then
call a bfd function (separate from the bfd vector) that swaps the
object to the proper external representation appropriate for the Linux
arch the core is being generated for, and then writes the note.

Most Linux ports have the same prpsinfo_t type (layed out in memory as
per their ABIs, naturally).  Be default, for Linux, GDB will call
these two new functions:

/* Linux/most 32-bit archs.  */
extern char *elfcore_write_linux_prpsinfo32
  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);

/* Linux/most 64-bit archs.  */
extern char *elfcore_write_linux_prpsinfo64
  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);

GDB will select which depending on the target's pointer width.

PowerPC 32-bit however has a slightly different structure, so it gets
its own entry point:

/* Linux/PPC32 uses different layout compared to most archs.  */
extern char *elfcore_write_ppc_linux_prpsinfo32
  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);

Tested on x86_64 Fedora 17 by building GDB with --enable-targets=all,
in both 64-bit, and -m32 modes, and by running GDBs testsuite with
each build.  No regressions.

I haven't audited all Linux ports to see if like PPC their prpsinfo_t
types are not like the others'.

bfd/
2013-01-31  Sergio Durigan Junior  <sergiodj@redhat.com>
	    Pedro Alves  <palves@redhat.com>

	* Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
	* elf-bfd.h (elf_internal_linux_prpsinfo): New structure
	declaration.
	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64)
	(elfcore_write_ppc32_linux_prpsinfo32): New declarations.
	* elf-linux-psinfo.h: New file.
	* elf.c: Include elf-linux-psinfo.h.
	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64):
	New functions.
	* elf32-ppc.c: Include `elf-linux-psinfo.h'.
	(elf_external_ppc_linux_prpsinfo32): New structure declaration.
	(PPC_LINUX_PRPSINFO32_SWAP_FIELDS): New macro.
	(elfcore_write_ppc_linux_prpsinfo32): New function.
---
 0 files changed

diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index af4e5ed..a92debf 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1072,7 +1072,7 @@ BUILD_CFILES = \
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
-	elf-bfd.h elf-hppa.h elf32-hppa.h \
+	elf-bfd.h elf-linux-psinfo.h elf-hppa.h elf32-hppa.h \
 	elf64-hppa.h elfcode.h elfcore.h \
 	freebsd.h genlink.h go32stub.h \
 	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index faaf632..1fd73cf 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2285,6 +2285,42 @@ extern char *elfcore_write_lwpstatus
 extern char *elfcore_write_register_note
   (bfd *, char *, int *, const char *, const void *, int);
 
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of Linux core files.
+
+   This is an "internal" structure in the sense that it should be used
+   to pass information to BFD (via the `elfcore_write_linux_prpsinfo'
+   function), so things like endianess shouldn't be an issue.  This
+   structure will eventually be converted in one of the
+   `elf_external_linux_*' structures and written out to an output bfd
+   by one of the functions declared below.  */
+
+struct elf_internal_linux_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    char pr_fname[16 + 1];		/* Filename of executable.  */
+    char pr_psargs[80 + 1];		/* Initial part of arg list.  */
+  };
+
+/* Linux/most 32-bit archs.  */
+extern char *elfcore_write_linux_prpsinfo32
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/most 64-bit archs.  */
+extern char *elfcore_write_linux_prpsinfo64
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/PPC32 uses different layout compared to most archs.  */
+extern char *elfcore_write_ppc_linux_prpsinfo32
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
 extern bfd *_bfd_elf32_bfd_from_remote_memory
   (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
    int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
diff --git a/bfd/elf-linux-psinfo.h b/bfd/elf-linux-psinfo.h
new file mode 100644
index 0000000..c965284
--- /dev/null
+++ b/bfd/elf-linux-psinfo.h
@@ -0,0 +1,127 @@
+/* Definitions for PRPSINFO structures under ELF on GNU/Linux.
+   Copyright 2013 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#ifndef ELF_LINUX_PSINFO_H
+#define ELF_LINUX_PSINFO_H
+
+/* The PRPSINFO structures defined below are used by most
+   architectures, although some of them define their own versions
+   (like e.g., PPC).  */
+
+/* External 32-bit structure for PRPSINFO.  This structure is
+   ABI-defined, thus we choose to use char arrays here in order to
+   avoid dealing with different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note
+   section, as the PRPSINFO.  */
+
+struct elf_external_linux_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[2];
+    char pr_gid[2];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to swap (properly handling endianess) things from the
+   `elf_internal_linux_prpsinfo' structure to the
+   `elf_external_linux_prpsinfo32' structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit
+   type.  */
+
+#define LINUX_PRPSINFO32_SWAP_FIELDS(abfd, from, to)			\
+  do									\
+    {									\
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state);			\
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname);			\
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb);			\
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice);			\
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag);			\
+      H_PUT_16 (abfd, from->pr_uid, to.pr_uid);				\
+      H_PUT_16 (abfd, from->pr_gid, to.pr_gid);				\
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid);				\
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid);			\
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp);			\
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid);				\
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname));	\
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs));	\
+    } while (0)
+
+/* External 64-bit structure for PRPSINFO.  This structure is
+   ABI-defined, thus we choose to use char arrays here in order to
+   avoid dealing with different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note
+   section, as the PRPSINFO.  */
+
+struct elf_external_linux_prpsinfo64
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[8];			/* Flags.  */
+    char gap[4];
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to swap (properly handling endianess) things from the
+   `elf_internal_linux_prpsinfo' structure to the
+   `elf_external_linux_prpsinfo64' structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit
+   type.  */
+
+#define LINUX_PRPSINFO64_SWAP_FIELDS(abfd, from, to)			\
+  do									\
+    {									\
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state);			\
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname);			\
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb);			\
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice);			\
+      H_PUT_64 (abfd, from->pr_flag, to.pr_flag);			\
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid);				\
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid);				\
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid);				\
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid);			\
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp);			\
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid);				\
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname));	\
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs));	\
+    } while (0)
+
+#endif
diff --git a/bfd/elf.c b/bfd/elf.c
index 9cd3542..7ab3683 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -45,6 +45,7 @@ SECTION
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-linux-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -9159,6 +9160,34 @@ elfcore_write_prpsinfo (bfd  *abfd,
 }
 
 char *
+elfcore_write_linux_prpsinfo32
+  (bfd *abfd, char *buf, int *bufsiz,
+   const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_linux_prpsinfo32 data;
+
+  memset (&data, 0, sizeof (data));
+  LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
+			     &data, sizeof (data));
+}
+
+char *
+elfcore_write_linux_prpsinfo64
+  (bfd *abfd, char *buf, int *bufsiz,
+   const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_linux_prpsinfo64 data;
+
+  memset (&data, 0, sizeof (data));
+  LINUX_PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz,
+			     "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
+char *
 elfcore_write_prstatus (bfd *abfd,
 			char *buf,
 			int *bufsiz,
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 3f4e4bf..bf14206 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-linux-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -1777,6 +1778,58 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
 	 0xffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 };
+
+/* External 32-bit PPC structure for PRPSINFO.  This structure is
+   ABI-defined, thus we choose to use char arrays here in order to
+   avoid dealing with different types in different architectures.
+
+   The PPC 32-bit structure uses int for `pr_uid' and `pr_gid' while
+   most non-PPC architectures use `short int'.
+
+   This structure will ultimately be written in the corefile's note
+   section, as the PRPSINFO.  */
+
+struct elf_external_ppc_linux_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to swap (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PPC_LINUX_PRPSINFO32_SWAP_FIELDS(abfd, from, to)	      \
+  do								      \
+    {								      \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state);		      \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname);		      \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb);		      \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice);		      \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag);		      \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid);			      \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid);			      \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid);			      \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid);		      \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp);		      \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid);			      \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname));    \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
 \f
 /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
 
@@ -2212,6 +2265,19 @@ ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
+char *
+elfcore_write_ppc_linux_prpsinfo32 (bfd *abfd, char *buf, int *bufsiz,
+				      const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_ppc_linux_prpsinfo32 data;
+
+  memset (&data, 0, sizeof (data));
+  PPC_LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz,
+			     "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
 static char *
 ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 {


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/2] Put more info in NT_PRPSINFO Linux notes
  2013-01-31 17:19     ` Pedro Alves
  2013-01-31 23:04       ` [PATCH 1/2] New entry points for writing Linux NT_PRPSINFO notes Pedro Alves
@ 2013-01-31 23:05       ` Pedro Alves
  2013-02-03 21:05         ` Sergio Durigan Junior
  1 sibling, 1 reply; 13+ messages in thread
From: Pedro Alves @ 2013-01-31 23:05 UTC (permalink / raw)
  To: binutils; +Cc: jan.kratochvil, hongjiu.lu, gdb-patches, sergiodj

Currently only a few fields of prpsinfo_t on Linux (and elsewhere too)
are filled in when generating NT_PRPSINFO notes on core files --
namely, fname, psargs.  E.g., ppid, pgrg and sid are missing.  We
could do better.  The previous bfd patch added a new interface that
allows passing in the full prpsinfo_t struct to bfd.  This patch makes
GDB use it.

Most Linux kernel ports have the same prpsinfo_t type (layed out in
memory as per their ABIs, naturally).  Be default, for Linux, we'll
call these two new functions:

/* Linux/most 32-bit archs.  */
extern char *elfcore_write_linux_prpsinfo32
  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);

/* Linux/most 64-bit archs.  */
extern char *elfcore_write_linux_prpsinfo64
  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);

GDB will select which depending on the target's pointer width.

PowerPC 32-bit however has a slightly different structure, so it gets
its own entry point:

/* Linux/PPC32 uses different layout compared to most archs.  */
extern char *elfcore_write_ppc_linux_prpsinfo32
  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);

We add add a new gdbarch hook that PPC taps into, to override the
default bfd elfcore hook selection.

Tested on x86_64 Fedora 17 by building GDB with --enable-targets=all,
in both 64-bit, and -m32 modes, and by running GDBs testsuite with
each build.  No regressions.

I haven't audited all Linux ports to see if like PPC their prpsinfo_t
types are not like the others'.

I just noticed, right before pushing send, that linux_fill_prpsinfo
does a "stat" call on the host, while that should be a call on the
target.  Unfortunately, there's no target_fileio_stat method.
Fortunately, the RSP bits are already in place, and just we need to
add the target method and hook it to remote_fileio_stat on the remote
target (and to the host stat for native targets).

Meanwhile, comments on the whole approach?

2013-01-31  Sergio Durigan Junior  <sergiodj@redhat.com>
	    Denys Vlasenko  <dvlasenk@redhat.com>
	    Pedro Alves  <palves@redhat.com>

	* gdbarch.sh (elfcore_write_linux_prpsinfo): New F hook.
	(struct elf_internal_linux_prpsinfo): Forward declare.
	* gdbarch.h, gdbarch.c: Regenerate.
	* linux-tdep.c: Include `cli/cli-utils.h'.
	(linux_fill_prpsinfo): New function.
	(linux_make_corefile_notes): Use linux_fill_prpsinfo.  If there's
	an elfcore_write_linux_prpsinfo hook, use it, otherwise, use
	elfcore_write_linux_prpsinfo32 or elfcore_write_linux_prpsinfo64
	depending on gdbarch pointer bitness.
	* ppc-linux-tdep.c: Include elf-bfd.h.
	(ppc_linux_init_abi): Hook in elfcore_write_ppc_linux_prpsinfo32
	on 32-bit.
---
 gdb/gdbarch.c        |   33 ++++++++
 gdb/gdbarch.h        |   13 +++
 gdb/gdbarch.sh       |    8 ++
 gdb/linux-tdep.c     |  210 ++++++++++++++++++++++++++++++++++++++++++++++----
 gdb/ppc-linux-tdep.c |    8 ++
 5 files changed, 257 insertions(+), 15 deletions(-)

diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index e48c5a6..129268f 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -238,6 +238,7 @@ struct gdbarch
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
   struct core_regset_section * core_regset_sections;
   gdbarch_make_corefile_notes_ftype *make_corefile_notes;
+  gdbarch_elfcore_write_linux_prpsinfo_ftype *elfcore_write_linux_prpsinfo;
   gdbarch_find_memory_regions_ftype *find_memory_regions;
   gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
   gdbarch_core_pid_to_str_ftype *core_pid_to_str;
@@ -408,6 +409,7 @@ struct gdbarch startup_gdbarch =
   0,  /* regset_from_core_section */
   0,  /* core_regset_sections */
   0,  /* make_corefile_notes */
+  0,  /* elfcore_write_linux_prpsinfo */
   0,  /* find_memory_regions */
   0,  /* core_xfer_shared_libraries */
   0,  /* core_pid_to_str */
@@ -709,6 +711,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of fetch_pointer_argument, has predicate.  */
   /* Skip verify of regset_from_core_section, has predicate.  */
   /* Skip verify of make_corefile_notes, has predicate.  */
+  /* Skip verify of elfcore_write_linux_prpsinfo, has predicate.  */
   /* Skip verify of find_memory_regions, has predicate.  */
   /* Skip verify of core_xfer_shared_libraries, has predicate.  */
   /* Skip verify of core_pid_to_str, has predicate.  */
@@ -955,6 +958,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: elf_make_msymbol_special = <%s>\n",
                       host_address_to_string (gdbarch->elf_make_msymbol_special));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_elfcore_write_linux_prpsinfo_p() = %d\n",
+                      gdbarch_elfcore_write_linux_prpsinfo_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: elfcore_write_linux_prpsinfo = <%s>\n",
+                      host_address_to_string (gdbarch->elfcore_write_linux_prpsinfo));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: fast_tracepoint_valid_at = <%s>\n",
                       host_address_to_string (gdbarch->fast_tracepoint_valid_at));
   fprintf_unfiltered (file,
@@ -3368,6 +3377,30 @@ set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch,
 }
 
 int
+gdbarch_elfcore_write_linux_prpsinfo_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->elfcore_write_linux_prpsinfo != NULL;
+}
+
+char *
+gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->elfcore_write_linux_prpsinfo != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_elfcore_write_linux_prpsinfo called\n");
+  return gdbarch->elfcore_write_linux_prpsinfo (obfd, note_data, note_size, info);
+}
+
+void
+set_gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch,
+                                          gdbarch_elfcore_write_linux_prpsinfo_ftype elfcore_write_linux_prpsinfo)
+{
+  gdbarch->elfcore_write_linux_prpsinfo = elfcore_write_linux_prpsinfo;
+}
+
+int
 gdbarch_find_memory_regions_p (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 844653b..464c4b6 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -57,6 +57,7 @@ struct agent_expr;
 struct axs_value;
 struct stap_parse_info;
 struct ravenscar_arch_ops;
+struct elf_internal_linux_prpsinfo;
 
 /* The architecture associated with the inferior through the
    connection to the target.
@@ -736,6 +737,18 @@ typedef char * (gdbarch_make_corefile_notes_ftype) (struct gdbarch *gdbarch, bfd
 extern char * gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
 extern void set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch, gdbarch_make_corefile_notes_ftype *make_corefile_notes);
 
+/* The elfcore writer hook to use to write Linux prpsinfo notes to core
+   files.  Most Linux architectures use the same prpsinfo32 or
+   prpsinfo64 layouts, and so won't need to provide this hook, as we
+   call the Linux generic routines in bfd to write prpsinfo notes by
+   default. */
+
+extern int gdbarch_elfcore_write_linux_prpsinfo_p (struct gdbarch *gdbarch);
+
+typedef char * (gdbarch_elfcore_write_linux_prpsinfo_ftype) (bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info);
+extern char * gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info);
+extern void set_gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, gdbarch_elfcore_write_linux_prpsinfo_ftype *elfcore_write_linux_prpsinfo);
+
 /* Find core file memory regions */
 
 extern int gdbarch_find_memory_regions_p (struct gdbarch *gdbarch);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 030bd8b..92d4f0f 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -641,6 +641,13 @@ v:struct core_regset_section *:core_regset_sections:const char *name, int len:::
 # Create core file notes
 M:char *:make_corefile_notes:bfd *obfd, int *note_size:obfd, note_size
 
+# The elfcore writer hook to use to write Linux prpsinfo notes to core
+# files.  Most Linux architectures use the same prpsinfo32 or
+# prpsinfo64 layouts, and so won't need to provide this hook, as we
+# call the Linux generic routines in bfd to write prpsinfo notes by
+# default.
+F:char *:elfcore_write_linux_prpsinfo:bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info:obfd, note_data, note_size, info
+
 # Find core file memory regions
 M:int:find_memory_regions:find_memory_region_ftype func, void *data:func, data
 
@@ -1082,6 +1089,7 @@ struct agent_expr;
 struct axs_value;
 struct stap_parse_info;
 struct ravenscar_arch_ops;
+struct elf_internal_linux_prpsinfo;
 
 /* The architecture associated with the inferior through the
    connection to the target.
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 836da62..c1ae539 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -32,6 +32,7 @@
 #include "cli/cli-utils.h"
 #include "arch-utils.h"
 #include "gdb_obstack.h"
+#include "cli/cli-utils.h"
 
 #include <ctype.h>
 
@@ -1153,6 +1154,181 @@ linux_corefile_thread_callback (struct thread_info *info, void *data)
   return !args->note_data;
 }
 
+/* Fill the PRPSINFO structure with information about the process being
+   debugged.  Returns 1 in case of success, 0 for failures.  Please note that
+   even if the structure cannot be entirely filled (e.g., GDB was unable to
+   gather information about the process UID/GID), this function will still
+   return 1 since some information was already recorded.  It will only return
+   0 iff nothing can be gathered.  */
+
+static int
+linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p)
+{
+  /* The filename which we will use to obtain some info about the process.
+     We will basically use this to store the `/proc/PID/FILENAME' file.  */
+  char filename[100];
+  /* The full name of the program which generated the corefile.  */
+  char *fname;
+  /* The basename of the executable.  */
+  const char *basename;
+  /* The arguments of the program.  */
+  char *psargs;
+  char *infargs;
+  /* The contents of `/proc/PID/stat' file.  */
+  char *proc_stat;
+  /* The valid states of a process, according to the Linux kernel.  */
+  const char valid_states[] = "RSDTZW";
+  /* The program state.  */
+  const char *prog_state;
+  /* The state of the process.  */
+  char pr_sname;
+  /* The PID of the program which generated the corefile.  */
+  pid_t pid;
+  /* Process flags.  */
+  unsigned int pr_flag;
+  /* Process nice value.  */
+  long pr_nice;
+  /* The stat of the `/proc/PID/stat' file.  */
+  struct stat proc_st;
+  /* The number of fields read by `sscanf'.  */
+  int n_fields = 0;
+  /* Cleanups.  */
+  struct cleanup *c;
+  int i;
+
+  gdb_assert (p != NULL);
+
+  /* Obtaining PID and filename.  */
+  pid = ptid_get_pid (inferior_ptid);
+  xsnprintf (filename, sizeof (filename), "/proc/%u/cmdline", pid);
+  fname = target_fileio_read_stralloc (filename);
+
+  if (fname == NULL || *fname == '\0')
+    {
+      /* No program name was read, so we won't be able to retrieve more
+	 information about the process.  */
+      xfree (fname);
+      return 0;
+    }
+
+  c = make_cleanup (xfree, fname);
+  memset (p, 0, sizeof (*p));
+
+  /* Obtaining the file stat as well.  */
+  if (stat (filename, &proc_st) != 0)
+    {
+      warning (_("Could not stat file `%s': %s"), filename,
+	       safe_strerror (errno));
+      p->pr_uid = 0;
+      p->pr_gid = 0;
+    }
+  else
+    {
+      p->pr_uid = proc_st.st_uid;
+      p->pr_gid = proc_st.st_gid;
+    }
+
+  /* Defining the PID.  */
+  p->pr_pid = pid;
+
+  /* Copying the program name.  Only the basename matters.  */
+  basename = lbasename (fname);
+  strncpy (p->pr_fname, basename, sizeof (p->pr_fname));
+  p->pr_fname[sizeof (p->pr_fname) - 1] = '\0';
+
+  infargs = get_inferior_args ();
+
+  psargs = xstrdup (fname);
+  if (infargs != NULL)
+    psargs = reconcat (psargs, psargs, " ", infargs, NULL);
+
+  make_cleanup (xfree, psargs);
+
+  strncpy (p->pr_psargs, psargs, sizeof (p->pr_psargs));
+  p->pr_psargs[sizeof (p->pr_psargs) - 1] = '\0';
+
+  xsnprintf (filename, sizeof (filename), "/proc/%d/stat", (int) pid);
+  proc_stat = target_fileio_read_stralloc (filename);
+  make_cleanup (xfree, proc_stat);
+
+  if (proc_stat == NULL || *proc_stat == '\0')
+    {
+      /* Despite being unable to read more information about the
+	 process, we return 1 here because at least we have its
+	 command line, PID and arguments.  */
+      do_cleanups (c);
+      return 1;
+    }
+
+  /* Ok, we have the stats.  It's time to do a little parsing of the
+     contents of the buffer, so that we end up reading what we want.
+
+     The following parsing mechanism is strongly based on the
+     information generated by the `fs/proc/array.c' file, present in
+     the Linux kernel tree.  More details about how the information is
+     displayed can be obtained by seeing the manpage of proc(5),
+     specifically under the entry of `/proc/[pid]/stat'.  */
+
+  /* Getting rid of the PID, since we already have it.  */
+  while (isdigit (*proc_stat))
+    ++proc_stat;
+
+  proc_stat = skip_spaces (proc_stat);
+
+  /* Getting rid of the executable name, since we already have it.  We
+     know that this name will be in parentheses, so we can safely look
+     for the close-paren.  */
+  while (*proc_stat != ')')
+    ++proc_stat;
+  ++proc_stat;
+
+  proc_stat = skip_spaces (proc_stat);
+
+  n_fields = sscanf (proc_stat,
+		     "%c"		/* Process state.  */
+		     "%d%d%d"		/* Parent PID, group ID, session ID.  */
+		     "%*d%*d"		/* tty_nr, tpgid (not used).  */
+		     "%u"		/* Flags.  */
+		     "%*s%*s%*s%*s"	/* minflt, cminflt, majflt,
+					   cmajflt (not used).  */
+		     "%*s%*s%*s%*s"	/* utime, stime, cutime,
+					   cstime (not used).  */
+		     "%*s"		/* Priority (not used).  */
+		     "%ld",		/* Nice.  */
+		     &pr_sname,
+		     &p->pr_ppid, &p->pr_pgrp, &p->pr_sid,
+		     &pr_flag,
+		     &pr_nice);
+
+  if (n_fields != 6)
+    {
+      /* Again, we couldn't read the complementary information about
+	 the process state.  However, we already have minimal
+	 information, so we just return 1 here.  */
+      do_cleanups (c);
+      return 1;
+    }
+
+  /* Filling the structure fields.  */
+  prog_state = strchr (valid_states, pr_sname);
+  if (prog_state != NULL)
+    p->pr_state = prog_state - valid_states;
+  else
+    {
+      /* Zero means "Running".  */
+      p->pr_state = 0;
+    }
+
+  p->pr_sname = p->pr_state > 5 ? '.' : pr_sname;
+  p->pr_zomb = p->pr_sname == 'Z';
+  p->pr_nice = pr_nice;
+  p->pr_flag = pr_flag;
+
+  do_cleanups (c);
+
+  return 1;
+}
+
 /* Fills the "to_make_corefile_note" target vector.  Builds the note
    section for a corefile, and returns it in a malloc buffer.  */
 
@@ -1161,26 +1337,30 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size,
 			   linux_collect_thread_registers_ftype collect)
 {
   struct linux_corefile_thread_data thread_args;
+  struct elf_internal_linux_prpsinfo prpsinfo;
   char *note_data = NULL;
   gdb_byte *auxv;
   int auxv_len;
 
-  /* Process information.  */
-  if (get_exec_file (0))
+  if (linux_fill_prpsinfo (&prpsinfo))
     {
-      const char *fname = lbasename (get_exec_file (0));
-      char *psargs = xstrdup (fname);
-
-      if (get_inferior_args ())
-        psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
-			   (char *) NULL);
-
-      note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
-                                          fname, psargs);
-      xfree (psargs);
-
-      if (!note_data)
-	return NULL;
+      if (gdbarch_elfcore_write_linux_prpsinfo_p (gdbarch))
+	{
+	  note_data = gdbarch_elfcore_write_linux_prpsinfo (gdbarch, obfd,
+							    note_data, note_size,
+							    &prpsinfo);
+	}
+      else
+	{
+	  if (gdbarch_ptr_bit (gdbarch) == 64)
+	    note_data = elfcore_write_linux_prpsinfo64 (obfd,
+							note_data, note_size,
+							&prpsinfo);
+	  else
+	    note_data = elfcore_write_linux_prpsinfo32 (obfd,
+							note_data, note_size,
+							&prpsinfo);
+	}
     }
 
   /* Thread register information.  */
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 135dc75..224d76b 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -56,6 +56,7 @@
 #include "parser-defs.h"
 #include "user-regs.h"
 #include <ctype.h>
+#include "elf-bfd.h"            /* for elfcore_write_* */
 
 #include "features/rs6000/powerpc-32l.c"
 #include "features/rs6000/powerpc-altivec32l.c"
@@ -1777,6 +1778,13 @@ ppc_linux_init_abi (struct gdbarch_info info,
 	set_gdbarch_core_regset_sections (gdbarch,
 					  ppc64_linux_fp_regset_sections);
     }
+
+  /* PPC32 uses a different prpsinfo32 compared to most other Linux
+     archs.  */
+  if (tdep->wordsize == 4)
+    set_gdbarch_elfcore_write_linux_prpsinfo (gdbarch,
+					      elfcore_write_ppc_linux_prpsinfo32);
+
   set_gdbarch_regset_from_core_section (gdbarch,
 					ppc_linux_regset_from_core_section);
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] New entry points for writing Linux NT_PRPSINFO notes.
  2013-01-31 23:04       ` [PATCH 1/2] New entry points for writing Linux NT_PRPSINFO notes Pedro Alves
@ 2013-02-01  6:37         ` Alan Modra
  2013-02-03  2:51           ` Sergio Durigan Junior
  2013-02-04 18:31           ` Sergio Durigan Junior
  0 siblings, 2 replies; 13+ messages in thread
From: Alan Modra @ 2013-02-01  6:37 UTC (permalink / raw)
  To: Pedro Alves; +Cc: binutils, jan.kratochvil, hongjiu.lu, gdb-patches, sergiodj

On Thu, Jan 31, 2013 at 11:04:38PM +0000, Pedro Alves wrote:
> 	* Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
> 	* elf-bfd.h (elf_internal_linux_prpsinfo): New structure
> 	declaration.
> 	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64)
> 	(elfcore_write_ppc32_linux_prpsinfo32): New declarations.
> 	* elf-linux-psinfo.h: New file.
> 	* elf.c: Include elf-linux-psinfo.h.
> 	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64):
> 	New functions.
> 	* elf32-ppc.c: Include `elf-linux-psinfo.h'.
> 	(elf_external_ppc_linux_prpsinfo32): New structure declaration.
> 	(PPC_LINUX_PRPSINFO32_SWAP_FIELDS): New macro.
> 	(elfcore_write_ppc_linux_prpsinfo32): New function.

Looks good to me.

-- 
Alan Modra
Australia Development Lab, IBM


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] New entry points for writing Linux NT_PRPSINFO notes.
  2013-02-01  6:37         ` Alan Modra
@ 2013-02-03  2:51           ` Sergio Durigan Junior
  2013-02-04 18:31           ` Sergio Durigan Junior
  1 sibling, 0 replies; 13+ messages in thread
From: Sergio Durigan Junior @ 2013-02-03  2:51 UTC (permalink / raw)
  To: Pedro Alves; +Cc: binutils, jan.kratochvil, hongjiu.lu, gdb-patches

On Friday, February 01 2013, Alan Modra wrote:

> On Thu, Jan 31, 2013 at 11:04:38PM +0000, Pedro Alves wrote:
>> 	* Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
>> 	* elf-bfd.h (elf_internal_linux_prpsinfo): New structure
>> 	declaration.
>> 	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64)
>> 	(elfcore_write_ppc32_linux_prpsinfo32): New declarations.
>> 	* elf-linux-psinfo.h: New file.
>> 	* elf.c: Include elf-linux-psinfo.h.
>> 	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64):
>> 	New functions.
>> 	* elf32-ppc.c: Include `elf-linux-psinfo.h'.
>> 	(elf_external_ppc_linux_prpsinfo32): New structure declaration.
>> 	(PPC_LINUX_PRPSINFO32_SWAP_FIELDS): New macro.
>> 	(elfcore_write_ppc_linux_prpsinfo32): New function.
>
> Looks good to me.

Thanks Pedro for the patch, and Alan for the review.

I know the patch has been approved, but just for the record I would like
to emit my opinion about it.  As I said to Pedro offlist, I would take
his suggestion of "getting rid of the middle man" a little bit further:
I would have created those Linux-specific functions for handling the
PRPSINFO note inside GDB, and not inside BFD.  I think this is a little
better because:

1) It does not contribute to the mess that is going on inside this area
of BFD, by just leaving things as-is, without introducing more
specialized functions that will have to be maintained later, and

2) As Pedro said in the message, it could make use of the already
existing GDB target sniffer, which would allow us to extend this later
to other targets without having to worry about making more and more
functions on bfd/elf-bfd.h.

I know that this approach has the drawback of putting some low level
logic that should be in BFD inside GDB, but IMO it's a small price to
pay.  Those functions inside GDB would still call `elfcore_write_note'
and make the byte swapping just as the `elf_write_linux_prpsinfo*' in
this patch, so the writing mechanism would still be inside BFD.

Anyway, I just would like to keep my opinion registered, in case we
choose to tackle this problem again in the future.

BTW, I plan to commit this patch as soon as the GDB side of it gets
approved, but I don't have write permission to the binutils repository
yet.  Alan (or some other binutils maintainer reading this), is it OK if
I send a message to overseers Ccing you asking for write permission?

Thanks,

-- 
Sergio


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] Put more info in NT_PRPSINFO Linux notes
  2013-01-31 23:05       ` [PATCH 2/2] Put more info in NT_PRPSINFO Linux notes Pedro Alves
@ 2013-02-03 21:05         ` Sergio Durigan Junior
  2013-02-04 16:36           ` Pedro Alves
  0 siblings, 1 reply; 13+ messages in thread
From: Sergio Durigan Junior @ 2013-02-03 21:05 UTC (permalink / raw)
  To: Pedro Alves; +Cc: binutils, jan.kratochvil, hongjiu.lu, gdb-patches

On Thursday, January 31 2013, Pedro Alves wrote:

> I just noticed, right before pushing send, that linux_fill_prpsinfo
> does a "stat" call on the host, while that should be a call on the
> target.  Unfortunately, there's no target_fileio_stat method.
> Fortunately, the RSP bits are already in place, and just we need to
> add the target method and hook it to remote_fileio_stat on the remote
> target (and to the host stat for native targets).

Thanks.

I am still hacking on the remote code in order to implement the stat
operation on it, but I noticed that it will involve some more time so I
decided to do a different approach in order to get this patch in.

What I did was basically read (via target_fileio_read_stralloc) and
parse the `/proc/PID/status' file, which contains both UID and GID
numbers (the only information I need from the `stat' call after all).
It was easy enough to do and worked fine on all targets, so I'm sending
this version of the patch for review and hopefully approval.  The
ChangeLog entry is still the same, and everything else is untouched
except for the linux_fill_prpsinfo function.

OK to apply?

-- 
Sergio

---
 gdb/gdbarch.c        |   33 +++++++
 gdb/gdbarch.h        |   13 +++
 gdb/gdbarch.sh       |    8 ++
 gdb/linux-tdep.c     |  235 ++++++++++++++++++++++++++++++++++++++++++++++---
 gdb/ppc-linux-tdep.c |    8 ++
 5 files changed, 282 insertions(+), 15 deletions(-)

diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index e48c5a6..129268f 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -238,6 +238,7 @@ struct gdbarch
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
   struct core_regset_section * core_regset_sections;
   gdbarch_make_corefile_notes_ftype *make_corefile_notes;
+  gdbarch_elfcore_write_linux_prpsinfo_ftype *elfcore_write_linux_prpsinfo;
   gdbarch_find_memory_regions_ftype *find_memory_regions;
   gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
   gdbarch_core_pid_to_str_ftype *core_pid_to_str;
@@ -408,6 +409,7 @@ struct gdbarch startup_gdbarch =
   0,  /* regset_from_core_section */
   0,  /* core_regset_sections */
   0,  /* make_corefile_notes */
+  0,  /* elfcore_write_linux_prpsinfo */
   0,  /* find_memory_regions */
   0,  /* core_xfer_shared_libraries */
   0,  /* core_pid_to_str */
@@ -709,6 +711,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of fetch_pointer_argument, has predicate.  */
   /* Skip verify of regset_from_core_section, has predicate.  */
   /* Skip verify of make_corefile_notes, has predicate.  */
+  /* Skip verify of elfcore_write_linux_prpsinfo, has predicate.  */
   /* Skip verify of find_memory_regions, has predicate.  */
   /* Skip verify of core_xfer_shared_libraries, has predicate.  */
   /* Skip verify of core_pid_to_str, has predicate.  */
@@ -955,6 +958,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: elf_make_msymbol_special = <%s>\n",
                       host_address_to_string (gdbarch->elf_make_msymbol_special));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_elfcore_write_linux_prpsinfo_p() = %d\n",
+                      gdbarch_elfcore_write_linux_prpsinfo_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: elfcore_write_linux_prpsinfo = <%s>\n",
+                      host_address_to_string (gdbarch->elfcore_write_linux_prpsinfo));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: fast_tracepoint_valid_at = <%s>\n",
                       host_address_to_string (gdbarch->fast_tracepoint_valid_at));
   fprintf_unfiltered (file,
@@ -3368,6 +3377,30 @@ set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch,
 }
 
 int
+gdbarch_elfcore_write_linux_prpsinfo_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->elfcore_write_linux_prpsinfo != NULL;
+}
+
+char *
+gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->elfcore_write_linux_prpsinfo != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_elfcore_write_linux_prpsinfo called\n");
+  return gdbarch->elfcore_write_linux_prpsinfo (obfd, note_data, note_size, info);
+}
+
+void
+set_gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch,
+                                          gdbarch_elfcore_write_linux_prpsinfo_ftype elfcore_write_linux_prpsinfo)
+{
+  gdbarch->elfcore_write_linux_prpsinfo = elfcore_write_linux_prpsinfo;
+}
+
+int
 gdbarch_find_memory_regions_p (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 844653b..464c4b6 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -57,6 +57,7 @@ struct agent_expr;
 struct axs_value;
 struct stap_parse_info;
 struct ravenscar_arch_ops;
+struct elf_internal_linux_prpsinfo;
 
 /* The architecture associated with the inferior through the
    connection to the target.
@@ -736,6 +737,18 @@ typedef char * (gdbarch_make_corefile_notes_ftype) (struct gdbarch *gdbarch, bfd
 extern char * gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
 extern void set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch, gdbarch_make_corefile_notes_ftype *make_corefile_notes);
 
+/* The elfcore writer hook to use to write Linux prpsinfo notes to core
+   files.  Most Linux architectures use the same prpsinfo32 or
+   prpsinfo64 layouts, and so won't need to provide this hook, as we
+   call the Linux generic routines in bfd to write prpsinfo notes by
+   default. */
+
+extern int gdbarch_elfcore_write_linux_prpsinfo_p (struct gdbarch *gdbarch);
+
+typedef char * (gdbarch_elfcore_write_linux_prpsinfo_ftype) (bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info);
+extern char * gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info);
+extern void set_gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, gdbarch_elfcore_write_linux_prpsinfo_ftype *elfcore_write_linux_prpsinfo);
+
 /* Find core file memory regions */
 
 extern int gdbarch_find_memory_regions_p (struct gdbarch *gdbarch);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 030bd8b..92d4f0f 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -641,6 +641,13 @@ v:struct core_regset_section *:core_regset_sections:const char *name, int len:::
 # Create core file notes
 M:char *:make_corefile_notes:bfd *obfd, int *note_size:obfd, note_size
 
+# The elfcore writer hook to use to write Linux prpsinfo notes to core
+# files.  Most Linux architectures use the same prpsinfo32 or
+# prpsinfo64 layouts, and so won't need to provide this hook, as we
+# call the Linux generic routines in bfd to write prpsinfo notes by
+# default.
+F:char *:elfcore_write_linux_prpsinfo:bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info:obfd, note_data, note_size, info
+
 # Find core file memory regions
 M:int:find_memory_regions:find_memory_region_ftype func, void *data:func, data
 
@@ -1082,6 +1089,7 @@ struct agent_expr;
 struct axs_value;
 struct stap_parse_info;
 struct ravenscar_arch_ops;
+struct elf_internal_linux_prpsinfo;
 
 /* The architecture associated with the inferior through the
    connection to the target.
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 836da62..04afbb1 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -32,6 +32,7 @@
 #include "cli/cli-utils.h"
 #include "arch-utils.h"
 #include "gdb_obstack.h"
+#include "cli/cli-utils.h"
 
 #include <ctype.h>
 
@@ -1153,6 +1154,206 @@ linux_corefile_thread_callback (struct thread_info *info, void *data)
   return !args->note_data;
 }
 
+/* Fill the PRPSINFO structure with information about the process being
+   debugged.  Returns 1 in case of success, 0 for failures.  Please note that
+   even if the structure cannot be entirely filled (e.g., GDB was unable to
+   gather information about the process UID/GID), this function will still
+   return 1 since some information was already recorded.  It will only return
+   0 iff nothing can be gathered.  */
+
+static int
+linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p)
+{
+  /* The filename which we will use to obtain some info about the process.
+     We will basically use this to store the `/proc/PID/FILENAME' file.  */
+  char filename[100];
+  /* The full name of the program which generated the corefile.  */
+  char *fname;
+  /* The basename of the executable.  */
+  const char *basename;
+  /* The arguments of the program.  */
+  char *psargs;
+  char *infargs;
+  /* The contents of `/proc/PID/stat' and `/proc/PID/status' files.  */
+  char *proc_stat, *proc_status;
+  /* Temporary buffer.  */
+  char *tmpstr;
+  /* The valid states of a process, according to the Linux kernel.  */
+  const char valid_states[] = "RSDTZW";
+  /* The program state.  */
+  const char *prog_state;
+  /* The state of the process.  */
+  char pr_sname;
+  /* The PID of the program which generated the corefile.  */
+  pid_t pid;
+  /* Process flags.  */
+  unsigned int pr_flag;
+  /* Process nice value.  */
+  long pr_nice;
+  /* The number of fields read by `sscanf'.  */
+  int n_fields = 0;
+  /* Cleanups.  */
+  struct cleanup *c;
+  int i;
+
+  gdb_assert (p != NULL);
+
+  /* Obtaining PID and filename.  */
+  pid = ptid_get_pid (inferior_ptid);
+  xsnprintf (filename, sizeof (filename), "/proc/%d/cmdline", (int) pid);
+  fname = target_fileio_read_stralloc (filename);
+
+  if (fname == NULL || *fname == '\0')
+    {
+      /* No program name was read, so we won't be able to retrieve more
+	 information about the process.  */
+      xfree (fname);
+      return 0;
+    }
+
+  c = make_cleanup (xfree, fname);
+  memset (p, 0, sizeof (*p));
+
+  /* Defining the PID.  */
+  p->pr_pid = pid;
+
+  /* Copying the program name.  Only the basename matters.  */
+  basename = lbasename (fname);
+  strncpy (p->pr_fname, basename, sizeof (p->pr_fname));
+  p->pr_fname[sizeof (p->pr_fname) - 1] = '\0';
+
+  infargs = get_inferior_args ();
+
+  psargs = xstrdup (fname);
+  if (infargs != NULL)
+    psargs = reconcat (psargs, psargs, " ", infargs, NULL);
+
+  make_cleanup (xfree, psargs);
+
+  strncpy (p->pr_psargs, psargs, sizeof (p->pr_psargs));
+  p->pr_psargs[sizeof (p->pr_psargs) - 1] = '\0';
+
+  xsnprintf (filename, sizeof (filename), "/proc/%d/stat", (int) pid);
+  proc_stat = target_fileio_read_stralloc (filename);
+  make_cleanup (xfree, proc_stat);
+
+  if (proc_stat == NULL || *proc_stat == '\0')
+    {
+      /* Despite being unable to read more information about the
+	 process, we return 1 here because at least we have its
+	 command line, PID and arguments.  */
+      do_cleanups (c);
+      return 1;
+    }
+
+  /* Ok, we have the stats.  It's time to do a little parsing of the
+     contents of the buffer, so that we end up reading what we want.
+
+     The following parsing mechanism is strongly based on the
+     information generated by the `fs/proc/array.c' file, present in
+     the Linux kernel tree.  More details about how the information is
+     displayed can be obtained by seeing the manpage of proc(5),
+     specifically under the entry of `/proc/[pid]/stat'.  */
+
+  /* Getting rid of the PID, since we already have it.  */
+  while (isdigit (*proc_stat))
+    ++proc_stat;
+
+  proc_stat = skip_spaces (proc_stat);
+
+  /* Getting rid of the executable name, since we already have it.  We
+     know that this name will be in parentheses, so we can safely look
+     for the close-paren.  */
+  while (*proc_stat != ')')
+    ++proc_stat;
+  ++proc_stat;
+
+  proc_stat = skip_spaces (proc_stat);
+
+  n_fields = sscanf (proc_stat,
+		     "%c"		/* Process state.  */
+		     "%d%d%d"		/* Parent PID, group ID, session ID.  */
+		     "%*d%*d"		/* tty_nr, tpgid (not used).  */
+		     "%u"		/* Flags.  */
+		     "%*s%*s%*s%*s"	/* minflt, cminflt, majflt,
+					   cmajflt (not used).  */
+		     "%*s%*s%*s%*s"	/* utime, stime, cutime,
+					   cstime (not used).  */
+		     "%*s"		/* Priority (not used).  */
+		     "%ld",		/* Nice.  */
+		     &pr_sname,
+		     &p->pr_ppid, &p->pr_pgrp, &p->pr_sid,
+		     &pr_flag,
+		     &pr_nice);
+
+  if (n_fields != 6)
+    {
+      /* Again, we couldn't read the complementary information about
+	 the process state.  However, we already have minimal
+	 information, so we just return 1 here.  */
+      do_cleanups (c);
+      return 1;
+    }
+
+  /* Filling the structure fields.  */
+  prog_state = strchr (valid_states, pr_sname);
+  if (prog_state != NULL)
+    p->pr_state = prog_state - valid_states;
+  else
+    {
+      /* Zero means "Running".  */
+      p->pr_state = 0;
+    }
+
+  p->pr_sname = p->pr_state > 5 ? '.' : pr_sname;
+  p->pr_zomb = p->pr_sname == 'Z';
+  p->pr_nice = pr_nice;
+  p->pr_flag = pr_flag;
+
+  /* Finally, obtaining the UID and GID.  For that, we read and parse the
+     contents of the `/proc/PID/status' file.  */
+  xsnprintf (filename, sizeof (filename), "/proc/%d/status", (int) pid);
+  proc_status = target_fileio_read_stralloc (filename);
+  make_cleanup (xfree, proc_status);
+
+  if (proc_status == NULL || *proc_status == '\0')
+    {
+      /* Returning 1 since we already have a bunch of information.  */
+      do_cleanups (c);
+      return 1;
+    }
+
+  /* Extracting the UID.  */
+  tmpstr = strstr (proc_status, "Uid:");
+  if (tmpstr != NULL)
+    {
+      /* Advancing the pointer to the beginning of the UID.  */
+      tmpstr += sizeof ("Uid:");
+      while (*tmpstr != '\0' && !isdigit (*tmpstr))
+	++tmpstr;
+
+      if (isdigit (*tmpstr))
+	p->pr_uid = strtol (tmpstr, &tmpstr, 10);
+    }
+
+  /* Extracting the GID.  */
+  tmpstr = strstr (proc_status, "Gid:");
+  if (tmpstr != NULL)
+    {
+      /* Advancing the pointer to the beginning of the GID.  */
+      tmpstr += sizeof ("Gid:");
+      while (*tmpstr != '\0' && !isdigit (*tmpstr))
+	++tmpstr;
+
+      if (isdigit (*tmpstr))
+	p->pr_gid = strtol (tmpstr, &tmpstr, 10);
+    }
+
+  do_cleanups (c);
+
+  return 1;
+}
+
 /* Fills the "to_make_corefile_note" target vector.  Builds the note
    section for a corefile, and returns it in a malloc buffer.  */
 
@@ -1161,26 +1362,30 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size,
 			   linux_collect_thread_registers_ftype collect)
 {
   struct linux_corefile_thread_data thread_args;
+  struct elf_internal_linux_prpsinfo prpsinfo;
   char *note_data = NULL;
   gdb_byte *auxv;
   int auxv_len;
 
-  /* Process information.  */
-  if (get_exec_file (0))
+  if (linux_fill_prpsinfo (&prpsinfo))
     {
-      const char *fname = lbasename (get_exec_file (0));
-      char *psargs = xstrdup (fname);
-
-      if (get_inferior_args ())
-        psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
-			   (char *) NULL);
-
-      note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
-                                          fname, psargs);
-      xfree (psargs);
-
-      if (!note_data)
-	return NULL;
+      if (gdbarch_elfcore_write_linux_prpsinfo_p (gdbarch))
+	{
+	  note_data = gdbarch_elfcore_write_linux_prpsinfo (gdbarch, obfd,
+							    note_data, note_size,
+							    &prpsinfo);
+	}
+      else
+	{
+	  if (gdbarch_ptr_bit (gdbarch) == 64)
+	    note_data = elfcore_write_linux_prpsinfo64 (obfd,
+							note_data, note_size,
+							&prpsinfo);
+	  else
+	    note_data = elfcore_write_linux_prpsinfo32 (obfd,
+							note_data, note_size,
+							&prpsinfo);
+	}
     }
 
   /* Thread register information.  */
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index cdf362f..7c2712d 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -57,6 +57,7 @@
 #include "parser-defs.h"
 #include "user-regs.h"
 #include <ctype.h>
+#include "elf-bfd.h"            /* for elfcore_write_* */
 
 #include "features/rs6000/powerpc-32l.c"
 #include "features/rs6000/powerpc-altivec32l.c"
@@ -1368,6 +1369,13 @@ ppc_linux_init_abi (struct gdbarch_info info,
 	set_gdbarch_core_regset_sections (gdbarch,
 					  ppc64_linux_fp_regset_sections);
     }
+
+  /* PPC32 uses a different prpsinfo32 compared to most other Linux
+     archs.  */
+  if (tdep->wordsize == 4)
+    set_gdbarch_elfcore_write_linux_prpsinfo (gdbarch,
+					      elfcore_write_ppc_linux_prpsinfo32);
+
   set_gdbarch_regset_from_core_section (gdbarch,
 					ppc_linux_regset_from_core_section);
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
-- 
1.7.7.6


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] Put more info in NT_PRPSINFO Linux notes
  2013-02-03 21:05         ` Sergio Durigan Junior
@ 2013-02-04 16:36           ` Pedro Alves
  2013-02-04 18:41             ` Sergio Durigan Junior
  0 siblings, 1 reply; 13+ messages in thread
From: Pedro Alves @ 2013-02-04 16:36 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Pedro Alves, binutils, jan.kratochvil, hongjiu.lu, gdb-patches

On 02/03/2013 09:05 PM, Sergio Durigan Junior wrote:
> On Thursday, January 31 2013, Pedro Alves wrote:
>
>> I just noticed, right before pushing send, that linux_fill_prpsinfo
>> does a "stat" call on the host, while that should be a call on the
>> target.  Unfortunately, there's no target_fileio_stat method.
>> Fortunately, the RSP bits are already in place, and just we need to
>> add the target method and hook it to remote_fileio_stat on the remote
>> target (and to the host stat for native targets).
>
> Thanks.
>
> I am still hacking on the remote code in order to implement the stat
> operation on it, but I noticed that it will involve some more time so I
> decided to do a different approach in order to get this patch in.

Good idea.  Then it sounds like the remote work won't be
necessary then.  Looking at the proc manual, or proc.txt in the kernel
I didn't find any indication that these fields weren't "always there".

> What I did was basically read (via target_fileio_read_stralloc) and
> parse the `/proc/PID/status' file, which contains both UID and GID
> numbers (the only information I need from the `stat' call after all).
> It was easy enough to do and worked fine on all targets, so I'm sending
> this version of the patch for review and hopefully approval.  

> The ChangeLog entry is still the same

(Please always paste it along with the patch, even if unchanged.
That's a good policy to avoid a reviewer having to go back
and forth between emails looking for the pieces.)

> and everything else is untouched
> except for the linux_fill_prpsinfo function.
> 
> OK to apply?

Looks good to me.  Thanks!

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] New entry points for writing Linux NT_PRPSINFO notes.
  2013-02-01  6:37         ` Alan Modra
  2013-02-03  2:51           ` Sergio Durigan Junior
@ 2013-02-04 18:31           ` Sergio Durigan Junior
  1 sibling, 0 replies; 13+ messages in thread
From: Sergio Durigan Junior @ 2013-02-04 18:31 UTC (permalink / raw)
  To: Pedro Alves; +Cc: binutils, jan.kratochvil, hongjiu.lu, gdb-patches

On Friday, February 01 2013, Alan Modra wrote:

> On Thu, Jan 31, 2013 at 11:04:38PM +0000, Pedro Alves wrote:
>> 	* Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
>> 	* elf-bfd.h (elf_internal_linux_prpsinfo): New structure
>> 	declaration.
>> 	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64)
>> 	(elfcore_write_ppc32_linux_prpsinfo32): New declarations.
>> 	* elf-linux-psinfo.h: New file.
>> 	* elf.c: Include elf-linux-psinfo.h.
>> 	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64):
>> 	New functions.
>> 	* elf32-ppc.c: Include `elf-linux-psinfo.h'.
>> 	(elf_external_ppc_linux_prpsinfo32): New structure declaration.
>> 	(PPC_LINUX_PRPSINFO32_SWAP_FIELDS): New macro.
>> 	(elfcore_write_ppc_linux_prpsinfo32): New function.
>
> Looks good to me.

Committed.

        http://sourceware.org/ml/binutils-cvs/2013-02/msg00015.html

-- 
Sergio

Index: bfd/ChangeLog
===================================================================
RCS file: /cvs/src/src/bfd/ChangeLog,v
retrieving revision 1.5928
diff -u -r1.5928 ChangeLog
--- bfd/ChangeLog	4 Feb 2013 14:48:20 -0000	1.5928
+++ bfd/ChangeLog	4 Feb 2013 18:25:02 -0000
@@ -1,3 +1,20 @@
+2013-02-04  Sergio Durigan Junior  <sergiodj@redhat.com>
+	    Pedro Alves  <palves@redhat.com>
+
+	* Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
+	* elf-bfd.h (elf_internal_linux_prpsinfo): New structure
+	declaration.
+	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64)
+	(elfcore_write_ppc32_linux_prpsinfo32): New declarations.
+	* elf-linux-psinfo.h: New file.
+	* elf.c: Include elf-linux-psinfo.h.
+	(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64):
+	New functions.
+	* elf32-ppc.c: Include `elf-linux-psinfo.h'.
+	(elf_external_ppc_linux_prpsinfo32): New structure declaration.
+	(PPC_LINUX_PRPSINFO32_SWAP_FIELDS): New macro.
+	(elfcore_write_ppc_linux_prpsinfo32): New function.
+
 2013-02-04  Tristan Gingold  <gingold@adacore.com>
 
 	* mach-o.c (bfd_mach_o_scan_start_address): Do not fail if no
Index: bfd/Makefile.in
===================================================================
RCS file: /cvs/src/src/bfd/Makefile.in,v
retrieving revision 1.300
diff -u -r1.300 Makefile.in
--- bfd/Makefile.in	4 Feb 2013 06:02:09 -0000	1.300
+++ bfd/Makefile.in	4 Feb 2013 18:25:02 -0000
@@ -1070,7 +1070,7 @@
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
-	elf-bfd.h elf-hppa.h elf32-hppa.h \
+	elf-bfd.h elf-linux-psinfo.h elf-hppa.h elf32-hppa.h \
 	elf64-hppa.h elfcode.h elfcore.h \
 	freebsd.h genlink.h go32stub.h \
 	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.355
diff -u -r1.355 elf-bfd.h
--- bfd/elf-bfd.h	13 Jan 2013 12:32:10 -0000	1.355
+++ bfd/elf-bfd.h	4 Feb 2013 18:25:03 -0000
@@ -2285,6 +2285,42 @@
 extern char *elfcore_write_register_note
   (bfd *, char *, int *, const char *, const void *, int);
 
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of Linux core files.
+
+   This is an "internal" structure in the sense that it should be used
+   to pass information to BFD (via the `elfcore_write_linux_prpsinfo'
+   function), so things like endianess shouldn't be an issue.  This
+   structure will eventually be converted in one of the
+   `elf_external_linux_*' structures and written out to an output bfd
+   by one of the functions declared below.  */
+
+struct elf_internal_linux_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    char pr_fname[16 + 1];		/* Filename of executable.  */
+    char pr_psargs[80 + 1];		/* Initial part of arg list.  */
+  };
+
+/* Linux/most 32-bit archs.  */
+extern char *elfcore_write_linux_prpsinfo32
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/most 64-bit archs.  */
+extern char *elfcore_write_linux_prpsinfo64
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/PPC32 uses different layout compared to most archs.  */
+extern char *elfcore_write_ppc_linux_prpsinfo32
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
 extern bfd *_bfd_elf32_bfd_from_remote_memory
   (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
    int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.581
diff -u -r1.581 elf.c
--- bfd/elf.c	8 Jan 2013 18:09:10 -0000	1.581
+++ bfd/elf.c	4 Feb 2013 18:25:04 -0000
@@ -45,6 +45,7 @@
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-linux-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -9159,6 +9160,34 @@
 }
 
 char *
+elfcore_write_linux_prpsinfo32
+  (bfd *abfd, char *buf, int *bufsiz,
+   const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_linux_prpsinfo32 data;
+
+  memset (&data, 0, sizeof (data));
+  LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
+			     &data, sizeof (data));
+}
+
+char *
+elfcore_write_linux_prpsinfo64
+  (bfd *abfd, char *buf, int *bufsiz,
+   const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_linux_prpsinfo64 data;
+
+  memset (&data, 0, sizeof (data));
+  LINUX_PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz,
+			     "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
+char *
 elfcore_write_prstatus (bfd *abfd,
 			char *buf,
 			int *bufsiz,
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.323
diff -u -r1.323 elf32-ppc.c
--- bfd/elf32-ppc.c	10 Jan 2013 20:03:53 -0000	1.323
+++ bfd/elf32-ppc.c	4 Feb 2013 18:25:05 -0000
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-linux-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -1777,6 +1778,58 @@
 	 0xffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 };
+
+/* External 32-bit PPC structure for PRPSINFO.  This structure is
+   ABI-defined, thus we choose to use char arrays here in order to
+   avoid dealing with different types in different architectures.
+
+   The PPC 32-bit structure uses int for `pr_uid' and `pr_gid' while
+   most non-PPC architectures use `short int'.
+
+   This structure will ultimately be written in the corefile's note
+   section, as the PRPSINFO.  */
+
+struct elf_external_ppc_linux_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to swap (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PPC_LINUX_PRPSINFO32_SWAP_FIELDS(abfd, from, to)	      \
+  do								      \
+    {								      \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state);		      \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname);		      \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb);		      \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice);		      \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag);		      \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid);			      \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid);			      \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid);			      \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid);		      \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp);		      \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid);			      \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname));    \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
 \f
 /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
 
@@ -2212,6 +2265,19 @@
   return TRUE;
 }
 
+char *
+elfcore_write_ppc_linux_prpsinfo32 (bfd *abfd, char *buf, int *bufsiz,
+				      const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_ppc_linux_prpsinfo32 data;
+
+  memset (&data, 0, sizeof (data));
+  PPC_LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz,
+			     "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
 static char *
 ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 {


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] Put more info in NT_PRPSINFO Linux notes
  2013-02-04 16:36           ` Pedro Alves
@ 2013-02-04 18:41             ` Sergio Durigan Junior
  0 siblings, 0 replies; 13+ messages in thread
From: Sergio Durigan Junior @ 2013-02-04 18:41 UTC (permalink / raw)
  To: Pedro Alves; +Cc: binutils, jan.kratochvil, hongjiu.lu, gdb-patches

On Monday, February 04 2013, Pedro Alves wrote:

> (Please always paste it along with the patch, even if unchanged.
> That's a good policy to avoid a reviewer having to go back
> and forth between emails looking for the pieces.)

Ok, sorry.

>> and everything else is untouched
>> except for the linux_fill_prpsinfo function.
>> 
>> OK to apply?
>
> Looks good to me.  Thanks!

Committed.

        http://sourceware.org/ml/gdb-cvs/2013-02/msg00034.html

Thanks,

-- 
Sergio

Index: gdb/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.15114
diff -u -r1.15114 ChangeLog
--- gdb/ChangeLog	4 Feb 2013 12:57:43 -0000	1.15114
+++ gdb/ChangeLog	4 Feb 2013 18:36:47 -0000
@@ -1,3 +1,20 @@
+2013-02-04  Sergio Durigan Junior  <sergiodj@redhat.com>
+	    Denys Vlasenko  <dvlasenk@redhat.com>
+	    Pedro Alves  <palves@redhat.com>
+
+	* gdbarch.sh (elfcore_write_linux_prpsinfo): New F hook.
+	(struct elf_internal_linux_prpsinfo): Forward declare.
+	* gdbarch.h, gdbarch.c: Regenerate.
+	* linux-tdep.c: Include `cli/cli-utils.h'.
+	(linux_fill_prpsinfo): New function.
+	(linux_make_corefile_notes): Use linux_fill_prpsinfo.  If there's
+	an elfcore_write_linux_prpsinfo hook, use it, otherwise, use
+	elfcore_write_linux_prpsinfo32 or elfcore_write_linux_prpsinfo64
+	depending on gdbarch pointer bitness.
+	* ppc-linux-tdep.c: Include elf-bfd.h.
+	(ppc_linux_init_abi): Hook in elfcore_write_ppc_linux_prpsinfo32
+	on 32-bit.
+
 2013-02-04  Jim MacArthur  <jim.macarthur@arm.com>
 	    Marcus Shawcroft  <marcus.shawcroft@arm.com>
 	    Nigel Stephens  <nigel.stephens@arm.com>
Index: gdb/gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.505
diff -u -r1.505 gdbarch.c
--- gdb/gdbarch.c	1 Jan 2013 06:32:42 -0000	1.505
+++ gdb/gdbarch.c	4 Feb 2013 18:36:47 -0000
@@ -238,6 +238,7 @@
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
   struct core_regset_section * core_regset_sections;
   gdbarch_make_corefile_notes_ftype *make_corefile_notes;
+  gdbarch_elfcore_write_linux_prpsinfo_ftype *elfcore_write_linux_prpsinfo;
   gdbarch_find_memory_regions_ftype *find_memory_regions;
   gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
   gdbarch_core_pid_to_str_ftype *core_pid_to_str;
@@ -408,6 +409,7 @@
   0,  /* regset_from_core_section */
   0,  /* core_regset_sections */
   0,  /* make_corefile_notes */
+  0,  /* elfcore_write_linux_prpsinfo */
   0,  /* find_memory_regions */
   0,  /* core_xfer_shared_libraries */
   0,  /* core_pid_to_str */
@@ -709,6 +711,7 @@
   /* Skip verify of fetch_pointer_argument, has predicate.  */
   /* Skip verify of regset_from_core_section, has predicate.  */
   /* Skip verify of make_corefile_notes, has predicate.  */
+  /* Skip verify of elfcore_write_linux_prpsinfo, has predicate.  */
   /* Skip verify of find_memory_regions, has predicate.  */
   /* Skip verify of core_xfer_shared_libraries, has predicate.  */
   /* Skip verify of core_pid_to_str, has predicate.  */
@@ -955,6 +958,12 @@
                       "gdbarch_dump: elf_make_msymbol_special = <%s>\n",
                       host_address_to_string (gdbarch->elf_make_msymbol_special));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_elfcore_write_linux_prpsinfo_p() = %d\n",
+                      gdbarch_elfcore_write_linux_prpsinfo_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: elfcore_write_linux_prpsinfo = <%s>\n",
+                      host_address_to_string (gdbarch->elfcore_write_linux_prpsinfo));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: fast_tracepoint_valid_at = <%s>\n",
                       host_address_to_string (gdbarch->fast_tracepoint_valid_at));
   fprintf_unfiltered (file,
@@ -3368,6 +3377,30 @@
 }
 
 int
+gdbarch_elfcore_write_linux_prpsinfo_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->elfcore_write_linux_prpsinfo != NULL;
+}
+
+char *
+gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->elfcore_write_linux_prpsinfo != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_elfcore_write_linux_prpsinfo called\n");
+  return gdbarch->elfcore_write_linux_prpsinfo (obfd, note_data, note_size, info);
+}
+
+void
+set_gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch,
+                                          gdbarch_elfcore_write_linux_prpsinfo_ftype elfcore_write_linux_prpsinfo)
+{
+  gdbarch->elfcore_write_linux_prpsinfo = elfcore_write_linux_prpsinfo;
+}
+
+int
 gdbarch_find_memory_regions_p (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
Index: gdb/gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.453
diff -u -r1.453 gdbarch.h
--- gdb/gdbarch.h	1 Jan 2013 06:32:43 -0000	1.453
+++ gdb/gdbarch.h	4 Feb 2013 18:36:47 -0000
@@ -57,6 +57,7 @@
 struct axs_value;
 struct stap_parse_info;
 struct ravenscar_arch_ops;
+struct elf_internal_linux_prpsinfo;
 
 /* The architecture associated with the inferior through the
    connection to the target.
@@ -736,6 +737,18 @@
 extern char * gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
 extern void set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch, gdbarch_make_corefile_notes_ftype *make_corefile_notes);
 
+/* The elfcore writer hook to use to write Linux prpsinfo notes to core
+   files.  Most Linux architectures use the same prpsinfo32 or
+   prpsinfo64 layouts, and so won't need to provide this hook, as we
+   call the Linux generic routines in bfd to write prpsinfo notes by
+   default. */
+
+extern int gdbarch_elfcore_write_linux_prpsinfo_p (struct gdbarch *gdbarch);
+
+typedef char * (gdbarch_elfcore_write_linux_prpsinfo_ftype) (bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info);
+extern char * gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info);
+extern void set_gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, gdbarch_elfcore_write_linux_prpsinfo_ftype *elfcore_write_linux_prpsinfo);
+
 /* Find core file memory regions */
 
 extern int gdbarch_find_memory_regions_p (struct gdbarch *gdbarch);
Index: gdb/gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.556
diff -u -r1.556 gdbarch.sh
--- gdb/gdbarch.sh	1 Jan 2013 06:32:44 -0000	1.556
+++ gdb/gdbarch.sh	4 Feb 2013 18:36:47 -0000
@@ -641,6 +641,13 @@
 # Create core file notes
 M:char *:make_corefile_notes:bfd *obfd, int *note_size:obfd, note_size
 
+# The elfcore writer hook to use to write Linux prpsinfo notes to core
+# files.  Most Linux architectures use the same prpsinfo32 or
+# prpsinfo64 layouts, and so won't need to provide this hook, as we
+# call the Linux generic routines in bfd to write prpsinfo notes by
+# default.
+F:char *:elfcore_write_linux_prpsinfo:bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info:obfd, note_data, note_size, info
+
 # Find core file memory regions
 M:int:find_memory_regions:find_memory_region_ftype func, void *data:func, data
 
@@ -1082,6 +1089,7 @@
 struct axs_value;
 struct stap_parse_info;
 struct ravenscar_arch_ops;
+struct elf_internal_linux_prpsinfo;
 
 /* The architecture associated with the inferior through the
    connection to the target.
Index: gdb/linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-tdep.c,v
retrieving revision 1.26
diff -u -r1.26 linux-tdep.c
--- gdb/linux-tdep.c	1 Jan 2013 06:32:46 -0000	1.26
+++ gdb/linux-tdep.c	4 Feb 2013 18:36:48 -0000
@@ -32,6 +32,7 @@
 #include "cli/cli-utils.h"
 #include "arch-utils.h"
 #include "gdb_obstack.h"
+#include "cli/cli-utils.h"
 
 #include <ctype.h>
 
@@ -1153,6 +1154,206 @@
   return !args->note_data;
 }
 
+/* Fill the PRPSINFO structure with information about the process being
+   debugged.  Returns 1 in case of success, 0 for failures.  Please note that
+   even if the structure cannot be entirely filled (e.g., GDB was unable to
+   gather information about the process UID/GID), this function will still
+   return 1 since some information was already recorded.  It will only return
+   0 iff nothing can be gathered.  */
+
+static int
+linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p)
+{
+  /* The filename which we will use to obtain some info about the process.
+     We will basically use this to store the `/proc/PID/FILENAME' file.  */
+  char filename[100];
+  /* The full name of the program which generated the corefile.  */
+  char *fname;
+  /* The basename of the executable.  */
+  const char *basename;
+  /* The arguments of the program.  */
+  char *psargs;
+  char *infargs;
+  /* The contents of `/proc/PID/stat' and `/proc/PID/status' files.  */
+  char *proc_stat, *proc_status;
+  /* Temporary buffer.  */
+  char *tmpstr;
+  /* The valid states of a process, according to the Linux kernel.  */
+  const char valid_states[] = "RSDTZW";
+  /* The program state.  */
+  const char *prog_state;
+  /* The state of the process.  */
+  char pr_sname;
+  /* The PID of the program which generated the corefile.  */
+  pid_t pid;
+  /* Process flags.  */
+  unsigned int pr_flag;
+  /* Process nice value.  */
+  long pr_nice;
+  /* The number of fields read by `sscanf'.  */
+  int n_fields = 0;
+  /* Cleanups.  */
+  struct cleanup *c;
+  int i;
+
+  gdb_assert (p != NULL);
+
+  /* Obtaining PID and filename.  */
+  pid = ptid_get_pid (inferior_ptid);
+  xsnprintf (filename, sizeof (filename), "/proc/%d/cmdline", (int) pid);
+  fname = target_fileio_read_stralloc (filename);
+
+  if (fname == NULL || *fname == '\0')
+    {
+      /* No program name was read, so we won't be able to retrieve more
+	 information about the process.  */
+      xfree (fname);
+      return 0;
+    }
+
+  c = make_cleanup (xfree, fname);
+  memset (p, 0, sizeof (*p));
+
+  /* Defining the PID.  */
+  p->pr_pid = pid;
+
+  /* Copying the program name.  Only the basename matters.  */
+  basename = lbasename (fname);
+  strncpy (p->pr_fname, basename, sizeof (p->pr_fname));
+  p->pr_fname[sizeof (p->pr_fname) - 1] = '\0';
+
+  infargs = get_inferior_args ();
+
+  psargs = xstrdup (fname);
+  if (infargs != NULL)
+    psargs = reconcat (psargs, psargs, " ", infargs, NULL);
+
+  make_cleanup (xfree, psargs);
+
+  strncpy (p->pr_psargs, psargs, sizeof (p->pr_psargs));
+  p->pr_psargs[sizeof (p->pr_psargs) - 1] = '\0';
+
+  xsnprintf (filename, sizeof (filename), "/proc/%d/stat", (int) pid);
+  proc_stat = target_fileio_read_stralloc (filename);
+  make_cleanup (xfree, proc_stat);
+
+  if (proc_stat == NULL || *proc_stat == '\0')
+    {
+      /* Despite being unable to read more information about the
+	 process, we return 1 here because at least we have its
+	 command line, PID and arguments.  */
+      do_cleanups (c);
+      return 1;
+    }
+
+  /* Ok, we have the stats.  It's time to do a little parsing of the
+     contents of the buffer, so that we end up reading what we want.
+
+     The following parsing mechanism is strongly based on the
+     information generated by the `fs/proc/array.c' file, present in
+     the Linux kernel tree.  More details about how the information is
+     displayed can be obtained by seeing the manpage of proc(5),
+     specifically under the entry of `/proc/[pid]/stat'.  */
+
+  /* Getting rid of the PID, since we already have it.  */
+  while (isdigit (*proc_stat))
+    ++proc_stat;
+
+  proc_stat = skip_spaces (proc_stat);
+
+  /* Getting rid of the executable name, since we already have it.  We
+     know that this name will be in parentheses, so we can safely look
+     for the close-paren.  */
+  while (*proc_stat != ')')
+    ++proc_stat;
+  ++proc_stat;
+
+  proc_stat = skip_spaces (proc_stat);
+
+  n_fields = sscanf (proc_stat,
+		     "%c"		/* Process state.  */
+		     "%d%d%d"		/* Parent PID, group ID, session ID.  */
+		     "%*d%*d"		/* tty_nr, tpgid (not used).  */
+		     "%u"		/* Flags.  */
+		     "%*s%*s%*s%*s"	/* minflt, cminflt, majflt,
+					   cmajflt (not used).  */
+		     "%*s%*s%*s%*s"	/* utime, stime, cutime,
+					   cstime (not used).  */
+		     "%*s"		/* Priority (not used).  */
+		     "%ld",		/* Nice.  */
+		     &pr_sname,
+		     &p->pr_ppid, &p->pr_pgrp, &p->pr_sid,
+		     &pr_flag,
+		     &pr_nice);
+
+  if (n_fields != 6)
+    {
+      /* Again, we couldn't read the complementary information about
+	 the process state.  However, we already have minimal
+	 information, so we just return 1 here.  */
+      do_cleanups (c);
+      return 1;
+    }
+
+  /* Filling the structure fields.  */
+  prog_state = strchr (valid_states, pr_sname);
+  if (prog_state != NULL)
+    p->pr_state = prog_state - valid_states;
+  else
+    {
+      /* Zero means "Running".  */
+      p->pr_state = 0;
+    }
+
+  p->pr_sname = p->pr_state > 5 ? '.' : pr_sname;
+  p->pr_zomb = p->pr_sname == 'Z';
+  p->pr_nice = pr_nice;
+  p->pr_flag = pr_flag;
+
+  /* Finally, obtaining the UID and GID.  For that, we read and parse the
+     contents of the `/proc/PID/status' file.  */
+  xsnprintf (filename, sizeof (filename), "/proc/%d/status", (int) pid);
+  proc_status = target_fileio_read_stralloc (filename);
+  make_cleanup (xfree, proc_status);
+
+  if (proc_status == NULL || *proc_status == '\0')
+    {
+      /* Returning 1 since we already have a bunch of information.  */
+      do_cleanups (c);
+      return 1;
+    }
+
+  /* Extracting the UID.  */
+  tmpstr = strstr (proc_status, "Uid:");
+  if (tmpstr != NULL)
+    {
+      /* Advancing the pointer to the beginning of the UID.  */
+      tmpstr += sizeof ("Uid:");
+      while (*tmpstr != '\0' && !isdigit (*tmpstr))
+	++tmpstr;
+
+      if (isdigit (*tmpstr))
+	p->pr_uid = strtol (tmpstr, &tmpstr, 10);
+    }
+
+  /* Extracting the GID.  */
+  tmpstr = strstr (proc_status, "Gid:");
+  if (tmpstr != NULL)
+    {
+      /* Advancing the pointer to the beginning of the GID.  */
+      tmpstr += sizeof ("Gid:");
+      while (*tmpstr != '\0' && !isdigit (*tmpstr))
+	++tmpstr;
+
+      if (isdigit (*tmpstr))
+	p->pr_gid = strtol (tmpstr, &tmpstr, 10);
+    }
+
+  do_cleanups (c);
+
+  return 1;
+}
+
 /* Fills the "to_make_corefile_note" target vector.  Builds the note
    section for a corefile, and returns it in a malloc buffer.  */
 
@@ -1161,26 +1362,30 @@
 			   linux_collect_thread_registers_ftype collect)
 {
   struct linux_corefile_thread_data thread_args;
+  struct elf_internal_linux_prpsinfo prpsinfo;
   char *note_data = NULL;
   gdb_byte *auxv;
   int auxv_len;
 
-  /* Process information.  */
-  if (get_exec_file (0))
+  if (linux_fill_prpsinfo (&prpsinfo))
     {
-      const char *fname = lbasename (get_exec_file (0));
-      char *psargs = xstrdup (fname);
-
-      if (get_inferior_args ())
-        psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
-			   (char *) NULL);
-
-      note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
-                                          fname, psargs);
-      xfree (psargs);
-
-      if (!note_data)
-	return NULL;
+      if (gdbarch_elfcore_write_linux_prpsinfo_p (gdbarch))
+	{
+	  note_data = gdbarch_elfcore_write_linux_prpsinfo (gdbarch, obfd,
+							    note_data, note_size,
+							    &prpsinfo);
+	}
+      else
+	{
+	  if (gdbarch_ptr_bit (gdbarch) == 64)
+	    note_data = elfcore_write_linux_prpsinfo64 (obfd,
+							note_data, note_size,
+							&prpsinfo);
+	  else
+	    note_data = elfcore_write_linux_prpsinfo32 (obfd,
+							note_data, note_size,
+							&prpsinfo);
+	}
     }
 
   /* Thread register information.  */
Index: gdb/ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.142
diff -u -r1.142 ppc-linux-tdep.c
--- gdb/ppc-linux-tdep.c	1 Feb 2013 20:54:18 -0000	1.142
+++ gdb/ppc-linux-tdep.c	4 Feb 2013 18:36:48 -0000
@@ -57,6 +57,7 @@
 #include "parser-defs.h"
 #include "user-regs.h"
 #include <ctype.h>
+#include "elf-bfd.h"            /* for elfcore_write_* */
 
 #include "features/rs6000/powerpc-32l.c"
 #include "features/rs6000/powerpc-altivec32l.c"
@@ -1368,6 +1369,13 @@
 	set_gdbarch_core_regset_sections (gdbarch,
 					  ppc64_linux_fp_regset_sections);
     }
+
+  /* PPC32 uses a different prpsinfo32 compared to most other Linux
+     archs.  */
+  if (tdep->wordsize == 4)
+    set_gdbarch_elfcore_write_linux_prpsinfo (gdbarch,
+					      elfcore_write_ppc_linux_prpsinfo32);
+
   set_gdbarch_regset_from_core_section (gdbarch,
 					ppc_linux_regset_from_core_section);
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-02-04 18:41 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-30  6:53 [PATCH 1/3] Implement new Linux target vectors on BFD Sergio Durigan Junior
2013-01-30  9:16 ` Alan Modra
2013-01-30 16:43   ` Sergio Durigan Junior
2013-01-31 17:19     ` Pedro Alves
2013-01-31 23:04       ` [PATCH 1/2] New entry points for writing Linux NT_PRPSINFO notes Pedro Alves
2013-02-01  6:37         ` Alan Modra
2013-02-03  2:51           ` Sergio Durigan Junior
2013-02-04 18:31           ` Sergio Durigan Junior
2013-01-31 23:05       ` [PATCH 2/2] Put more info in NT_PRPSINFO Linux notes Pedro Alves
2013-02-03 21:05         ` Sergio Durigan Junior
2013-02-04 16:36           ` Pedro Alves
2013-02-04 18:41             ` Sergio Durigan Junior
2013-01-30 16:44   ` [PATCH 1/3] Implement new Linux target vectors on BFD H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox