2006-09-23 Jan Kratochvil Fujitsu * amd64-linux-nat.c: Support new virtual_elfcore_write_prpsinfo, virtual_elfcore_write_prstatus, virtual_elfcore_write_prfpreg. (i386_linux_gregset32_reg_offset): New mapping for i386 on amd64. (amd64_linux_gcore_create_hook): New hook for modifying segment attrs. * gcore.c (gcore_create_hook): Hook function variable. (gcore_create_callback): Call (*gcore_create_hook). * configure.ac: Check for sys/user32.h, sys/procfs32.h. * configure, config.in: Regenerated. * linux-nat.c: Virtualize elfcore_*. (linux_nat_do_thread_registers): Likewise. (linux_nat_make_corefile_notes): Likewise. * linux-nat.h: Likewise. * Makefile.in: Dependencies updated. Index: gdb/Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.844 diff -u -p -r1.844 Makefile.in --- gdb/Makefile.in 21 Sep 2006 14:00:53 -0000 1.844 +++ gdb/Makefile.in 28 Sep 2006 15:40:06 -0000 @@ -704,6 +704,7 @@ gdb_h = gdb.h gdb_locale_h = gdb_locale.h gdb_obstack_h = gdb_obstack.h $(obstack_h) gdb_proc_service_h = gdb_proc_service.h $(gregset_h) +gdb_procfs32_h = gdb_procfs32.h $(gdb_user32_h) gdb_ptrace_h = gdb_ptrace.h gdb_regex_h = gdb_regex.h $(xregex_h) gdb_select_h = gdb_select.h @@ -713,6 +714,7 @@ gdb_string_h = gdb_string.h gdb_thread_db_h = gdb_thread_db.h gdbthread_h = gdbthread.h $(breakpoint_h) $(frame_h) gdbtypes_h = gdbtypes.h $(hashtab_h) +gdb_user32_h = gdb_user32.h gdb_vfork_h = gdb_vfork.h gdb_wait_h = gdb_wait.h glibc_tdep_h = glibc-tdep.h @@ -1746,7 +1748,8 @@ amd64fbsd-tdep.o: amd64fbsd-tdep.c $(def amd64-linux-nat.o: amd64-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \ $(regcache_h) $(linux_nat_h) $(gdb_assert_h) $(gdb_string_h) \ $(gdb_proc_service_h) $(gregset_h) $(amd64_tdep_h) \ - $(i386_linux_tdep_h) $(amd64_nat_h) $(target_h) $(amd64_linux_tdep_h) + $(i386_linux_tdep_h) $(amd64_nat_h) $(target_h) $(amd64_linux_tdep_h) \ + $(i387_tdep_h) $(elf_bfd_h) $(gdb_procfs32_h) amd64-linux-tdep.o: amd64-linux-tdep.c $(defs_h) $(frame_h) $(gdbcore_h) \ $(regcache_h) $(osabi_h) $(symtab_h) $(gdb_string_h) $(amd64_tdep_h) \ $(solib_svr4_h) $(gdbtypes_h) $(reggroups_h) $(amd64_linux_tdep_h) Index: gdb/amd64-linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/amd64-linux-nat.c,v retrieving revision 1.13 diff -u -p -r1.13 amd64-linux-nat.c --- gdb/amd64-linux-nat.c 19 Aug 2006 15:15:18 -0000 1.13 +++ gdb/amd64-linux-nat.c 28 Sep 2006 15:40:06 -0000 @@ -52,6 +52,9 @@ #include "amd64-tdep.h" #include "i386-linux-tdep.h" #include "amd64-nat.h" +#include "i387-tdep.h" +#include "bfd/elf-bfd.h" +#include "gdb_procfs32.h" /* Mapping between the general-purpose registers in GNU/Linux x86-64 `struct user' format and GDB's register cache layout. */ @@ -86,6 +89,35 @@ static int amd64_linux_gregset64_reg_off GNU/Linux i386 registers are all 32-bit, but since we're little-endian we get away with that. */ +/* This info is not reusable from "i386-linux-nat.c" as gdb itself runs in + 64-bit mode and so ptrace(2) has 64-bit structure layout. + Just the corefile being generated has 32-bit layout so we need to do + a conversion specific to the i386-on-amd64 compatibility mode. */ +static int i386_linux_gregset32_reg_offset[] = +{ + 6 * 4, /* %eax */ + 1 * 4, /* %ecx */ + 2 * 4, /* %edx */ + 0 * 4, /* %ebx */ + 15 * 4, /* %esp */ + 5 * 4, /* %ebp */ + 3 * 4, /* %esi */ + 4 * 4, /* %edi */ + 12 * 4, /* %eip */ + 14 * 4, /* %eflags */ + 13 * 4, /* %cs */ + 16 * 4, /* %ss */ + 7 * 4, /* %ds */ + 8 * 4, /* %es */ + 9 * 4, /* %fs */ + 10 * 4, /* %gs */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, + 11 * 4 /* "orig_eax" */ +}; + /* From on GNU/Linux i386. */ static int amd64_linux_gregset32_reg_offset[] = { @@ -104,6 +136,107 @@ static int amd64_linux_gregset32_reg_off }; +/* This functions make ELF32 32-bit elfcore note sections + on amd64 environment. */ + +static void +amd64_linux_gcore_create_hook (CORE_ADDR vaddr, int *read, int *write, + int *exec) +{ + /* VSYSCALL page is RWX==000 by default and gdb fails to read the library + header upon loading the core. */ + if (gdbarch_ptr_bit(current_gdbarch) == 32) + if (strcmp("ffffe000",paddr_nz(vaddr)) == 0 && + *read == 0 && *write == 0 && *exec == 0) { + *read = 1; + } +} + +static char * +amd64_linux_elfcore_write_prpsinfo (bfd *abfd, char *buf, int *bufsiz, + const char *fname, const char *psargs) +{ + if (gdbarch_ptr_bit(current_gdbarch) == 32) + { + int note_type; + char *note_name = "CORE"; + struct elf_prpsinfo32 data; + note_type = NT_PRPSINFO; + + memset (&data, 0, sizeof (data)); + strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); + strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); + return elfcore_write_note (abfd, buf, bufsiz, + note_name, note_type, &data, sizeof (data)); + } + else + return elfcore_write_prpsinfo (abfd, buf, bufsiz, fname, psargs); +} + +static void +amd64_linux_set_registers (char *gregs, char *buf) +{ + int i; + /* registers copy */ + for (i = 0; i < I386_NUM_GREGS; i++) + memcpy(buf + i386_linux_gregset32_reg_offset[i], + gregs + amd64_linux_gregset32_reg_offset[i], 4); + for (i = I386_CS_REGNUM; i <= I386_GS_REGNUM; i++) + memcpy(buf + i386_linux_gregset32_reg_offset[i], + gregs + amd64_linux_gregset32_reg_offset[i], 4); +} + +static char * +amd64_linux_elfcore_write_prstatus (bfd *abfd, char *buf, int *bufsiz, + long pid, int cursig, const void *gregs) +{ + if (gdbarch_ptr_bit(current_gdbarch) == 32) + { + char *note_name = "CORE"; + struct elf_prstatus32 prstat; + memset (&prstat, 0, sizeof (prstat)); + prstat.pr_pid = pid; + prstat.pr_cursig = cursig; + amd64_linux_set_registers ((char *)gregs, (char *)&prstat.pr_reg); + return elfcore_write_note (abfd, buf, bufsiz, note_name, + NT_PRSTATUS, &prstat, sizeof (prstat)); + } + else + return elfcore_write_prstatus (abfd, buf, bufsiz, pid, cursig, gregs); +} + +static char * +amd64_elfcore_write_prxfpreg32 (bfd *abfd, char *buf, int *bufsiz) +{ + char *note_name = "LINUX"; + elf_fpxregset32_t fpxregs32; + + i387_fill_fxsave ((char *) &fpxregs32, -1); + return (char *) elfcore_write_note(abfd, buf, bufsiz, + note_name, NT_PRXFPREG, &fpxregs32, + sizeof(fpxregs32)); +} + +static char * +amd64_linux_elfcore_write_prfpreg (bfd *abfd, char *buf, + int *bufsiz, const void *fpregs, int size) +{ + if (gdbarch_ptr_bit(current_gdbarch) == 32) + { + char *note_name = "CORE"; + elf_fpregset32_t fpregs32; + + i387_fill_fsave ((char *) &fpregs32, -1); + buf = elfcore_write_note(abfd, buf, bufsiz, note_name, + NT_FPREGSET, &fpregs32, sizeof(fpregs32)); + + return (char *) amd64_elfcore_write_prxfpreg32 (abfd, buf, bufsiz); + } + else + return elfcore_write_prfpreg (abfd, buf, bufsiz, fpregs, size); +} + + /* Transfering the general-purpose registers between GDB, inferiors and core files. */ @@ -377,6 +510,8 @@ amd64_linux_child_post_startup_inferior } +extern void (*gcore_create_hook) (CORE_ADDR, int *, int *, int *); + /* Provide a prototype to silence -Wmissing-prototypes. */ void _initialize_amd64_linux_nat (void); @@ -406,6 +541,13 @@ _initialize_amd64_linux_nat (void) t->to_fetch_registers = amd64_linux_fetch_inferior_registers; t->to_store_registers = amd64_linux_store_inferior_registers; + /* This functions make elfcore note sections. */ + virtual_elfcore_write_prpsinfo = amd64_linux_elfcore_write_prpsinfo; + virtual_elfcore_write_prstatus = amd64_linux_elfcore_write_prstatus; + virtual_elfcore_write_prfpreg = amd64_linux_elfcore_write_prfpreg; + + gcore_create_hook = amd64_linux_gcore_create_hook; + /* Register the target. */ linux_nat_add_target (t); } Index: gdb/config.in =================================================================== RCS file: /cvs/src/src/gdb/config.in,v retrieving revision 1.84 diff -u -p -r1.84 config.in --- gdb/config.in 8 Aug 2006 20:32:15 -0000 1.84 +++ gdb/config.in 28 Sep 2006 15:40:06 -0000 @@ -373,6 +373,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PROCFS32_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PROCFS_H @@ -397,6 +400,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_USER32_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_USER_H Index: gdb/configure =================================================================== RCS file: /cvs/src/src/gdb/configure,v retrieving revision 1.213 diff -u -p -r1.213 configure --- gdb/configure 8 Aug 2006 20:32:15 -0000 1.213 +++ gdb/configure 28 Sep 2006 15:40:09 -0000 @@ -9960,6 +9960,157 @@ done +for ac_header in sys/user32.h sys/procfs32.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + for ac_header in sys/wait.h wait.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` Index: gdb/configure.ac =================================================================== RCS file: /cvs/src/src/gdb/configure.ac,v retrieving revision 1.34 diff -u -p -r1.34 configure.ac --- gdb/configure.ac 8 Aug 2006 20:26:23 -0000 1.34 +++ gdb/configure.ac 28 Sep 2006 15:40:10 -0000 @@ -365,6 +365,7 @@ AC_CHECK_HEADERS(sys/user.h, [], [], # include #endif ]) +AC_CHECK_HEADERS(sys/user32.h sys/procfs32.h) AC_CHECK_HEADERS(sys/wait.h wait.h) AC_CHECK_HEADERS(termios.h termio.h sgtty.h) AC_CHECK_HEADERS(unistd.h) Index: gdb/gcore.c =================================================================== RCS file: /cvs/src/src/gdb/gcore.c,v retrieving revision 1.18 diff -u -p -r1.18 gcore.c --- gdb/gcore.c 17 Dec 2005 22:33:59 -0000 1.18 +++ gdb/gcore.c 28 Sep 2006 15:40:10 -0000 @@ -36,6 +36,9 @@ static enum bfd_architecture default_gco static unsigned long default_gcore_mach (void); static int gcore_memory_sections (bfd *); +/* This function is hook to adjust core file segment. */ +void (*gcore_create_hook) (CORE_ADDR, int *, int *, int *) = NULL; + /* Generate a core file from the inferior process. */ static void @@ -314,6 +317,9 @@ gcore_create_callback (CORE_ADDR vaddr, asection *osec; flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD; + if (gcore_create_hook) + gcore_create_hook (vaddr, &read, &write, &exec); + /* If the memory segment has no permissions set, ignore it, otherwise when we later try to access it for read/write, we'll get an error or jam the kernel. */ Index: gdb/gdb_procfs32.h =================================================================== RCS file: gdb/gdb_procfs32.h diff -N gdb/gdb_procfs32.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/gdb_procfs32.h 28 Sep 2006 15:40:10 -0000 @@ -0,0 +1,128 @@ +#ifdef HAVE_SYS_PROCFS32_H +#include +#else + +/* Copyright (C) 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SYS_PROCFS32_H +#define _SYS_PROCFS32_H 1 + +/* This is somewhat modelled after the file of the same name on SVR4 + systems. It provides a definition of the core file format for ELF + used on Linux. It doesn't have anything to do with the /proc file + system, even though Linux has one. + + Anyway, the whole purpose of this file is for GDB and GDB only. + Don't read too much into it. Don't use it for anything other than + GDB unless you know what you are doing. */ + +#include +#include +#include +#include "gdb_user32.h" + +/* We define here only the symbols differing from their 64-bit variant. */ +#include + +__BEGIN_DECLS + +/* Type for a general-purpose register. */ +typedef unsigned int elf_greg32_t; + +/* And the whole bunch of them. We could have used `struct + user_regs_struct' directly in the typedef, but tradition says that + the register set is an array, which does have some peculiar + semantics, so leave it that way. */ +#define ELF_NGREG32 (sizeof (struct user_regs32_struct) / sizeof(elf_greg32_t)) +typedef elf_greg32_t elf_gregset32_t[ELF_NGREG32]; + +/* Register set for the floating-point registers. */ +typedef struct user_fpregs32_struct elf_fpregset32_t; + +/* Register set for the extended floating-point registers. Includes + the Pentium III SSE registers in addition to the classic + floating-point stuff. */ +typedef struct user_fpxregs32_struct elf_fpxregset32_t; + + +/* Definitions to generate Intel SVR4-like core files. These mostly + have the same names as the SVR4 types with "elf_" tacked on the + front to prevent clashes with Linux definitions, and the typedef + forms have been avoided. This is mostly like the SVR4 structure, + but more Linuxy, with things that Linux does not support and which + GDB doesn't really use excluded. */ + +struct prstatus32_timeval + { + int tv_sec; + int tv_usec; + }; + +struct elf_prstatus32 + { + struct elf_siginfo pr_info; /* Info associated with signal. */ + short int pr_cursig; /* Current signal. */ + unsigned int pr_sigpend; /* Set of pending signals. */ + unsigned int pr_sighold; /* Set of held signals. */ + __pid_t pr_pid; + __pid_t pr_ppid; + __pid_t pr_pgrp; + __pid_t pr_sid; + struct prstatus32_timeval pr_utime; /* User time. */ + struct prstatus32_timeval pr_stime; /* System time. */ + struct prstatus32_timeval pr_cutime; /* Cumulative user time. */ + struct prstatus32_timeval pr_cstime; /* Cumulative system time. */ + elf_gregset32_t pr_reg; /* GP registers. */ + int pr_fpvalid; /* True if math copro being used. */ + }; + + +struct elf_prpsinfo32 + { + char pr_state; /* Numeric process state. */ + char pr_sname; /* Char for pr_state. */ + char pr_zomb; /* Zombie. */ + char pr_nice; /* Nice val. */ + unsigned int pr_flag; /* Flags. */ + unsigned short int pr_uid; + unsigned short int pr_gid; + int pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* Filename of executable. */ + char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */ + }; + + +/* The rest of this file provides the types for emulation of the + Solaris interfaces that should be implemented by + users of libthread_db. */ + +/* Register sets. Linux has different names. */ +typedef elf_gregset_t prgregset32_t; +typedef elf_fpregset_t prfpregset32_t; + +/* Process status and info. In the end we do provide typedefs for them. */ +typedef struct elf_prstatus32 prstatus32_t; +typedef struct elf_prpsinfo32 prpsinfo32_t; + +__END_DECLS + +#endif /* _SYS_PROCFS32_H */ + +#endif /* HAVE_SYS_PROCFS32_H */ Index: gdb/gdb_user32.h =================================================================== RCS file: gdb/gdb_user32.h diff -N gdb/gdb_user32.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/gdb_user32.h 28 Sep 2006 15:40:10 -0000 @@ -0,0 +1,108 @@ +#ifdef HAVE_SYS_USER32_H +#include +#else + +#ifdef HAVE_STDINT_H +#include +typedef int32_t gdb_int32_t; +typedef uint32_t gdb_uint32_t; +#else +typedef signed int gdb_uint32_t; +typedef unsigned int gdb_uint32_t; +#endif + +/* Copyright (C) 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SYS_USER32_H +#define _SYS_USER32_H 1 + +/* These are the 32-bit x86 structures. */ + +struct user_fpregs32_struct +{ + gdb_int32_t cwd; + gdb_int32_t swd; + gdb_int32_t twd; + gdb_int32_t fip; + gdb_int32_t fcs; + gdb_int32_t foo; + gdb_int32_t fos; + gdb_int32_t st_space [20]; +}; + +struct user_fpxregs32_struct +{ + unsigned short int cwd; + unsigned short int swd; + unsigned short int twd; + unsigned short int fop; + gdb_int32_t fip; + gdb_int32_t fcs; + gdb_int32_t foo; + gdb_int32_t fos; + gdb_int32_t mxcsr; + gdb_int32_t reserved; + gdb_int32_t st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + gdb_int32_t xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ + gdb_int32_t padding[56]; +}; + +struct user_regs32_struct +{ + gdb_int32_t ebx; + gdb_int32_t ecx; + gdb_int32_t edx; + gdb_int32_t esi; + gdb_int32_t edi; + gdb_int32_t ebp; + gdb_int32_t eax; + gdb_int32_t xds; + gdb_int32_t xes; + gdb_int32_t xfs; + gdb_int32_t xgs; + gdb_int32_t orig_eax; + gdb_int32_t eip; + gdb_int32_t xcs; + gdb_int32_t eflags; + gdb_int32_t esp; + gdb_int32_t xss; +}; + +struct user32 +{ + struct user_regs32_struct regs; + int u_fpvalid; + struct user_fpregs32_struct i387; + gdb_uint32_t u_tsize; + gdb_uint32_t u_dsize; + gdb_uint32_t u_ssize; + gdb_uint32_t start_code; + gdb_uint32_t start_stack; + gdb_int32_t signal; + int reserved; + struct user_regs32_struct* u_ar0; + struct user_fpregs32_struct* u_fpstate; + gdb_uint32_t magic; + char u_comm [32]; + int u_debugreg [8]; +}; + +#endif /* _SYS_USER32_H */ + +#endif /* HAVE_SYS_USER32_H */ Index: gdb/linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/linux-nat.c,v retrieving revision 1.50 diff -u -p -r1.50 linux-nat.c --- gdb/linux-nat.c 16 Sep 2006 09:48:12 -0000 1.50 +++ gdb/linux-nat.c 28 Sep 2006 15:40:11 -0000 @@ -99,6 +99,15 @@ static LONGEST (*super_xfer_partial) (st const gdb_byte *, ULONGEST, LONGEST); +/* This functions make elfcore note sections. + They may get overriden by code adjusting data for multi-target builds. */ +char *(*virtual_elfcore_write_prpsinfo) + (bfd *, char *, int *, const char *, const char *) = elfcore_write_prpsinfo; +char *(*virtual_elfcore_write_prstatus) + (bfd *, char *, int *, long, int, const void *) = elfcore_write_prstatus; +char *(*virtual_elfcore_write_prfpreg) + (bfd *, char *, int *, const void *, int) = elfcore_write_prfpreg; + static int debug_linux_nat; static void show_debug_linux_nat (struct ui_file *file, int from_tty, @@ -2562,11 +2571,11 @@ linux_nat_do_thread_registers (bfd *obfd else fill_gregset (&gregs, -1); - note_data = (char *) elfcore_write_prstatus (obfd, - note_data, - note_size, - lwp, - stop_signal, &gregs); + note_data = (char *) virtual_elfcore_write_prstatus (obfd, + note_data, + note_size, + lwp, + stop_signal, &gregs); if (core_regset_p && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", @@ -2577,10 +2586,10 @@ linux_nat_do_thread_registers (bfd *obfd else fill_fpregset (&fpregs, -1); - note_data = (char *) elfcore_write_prfpreg (obfd, - note_data, - note_size, - &fpregs, sizeof (fpregs)); + note_data = (char *) virtual_elfcore_write_prfpreg (obfd, + note_data, + note_size, + &fpregs, sizeof (fpregs)); #ifdef FILL_FPXREGSET if (core_regset_p @@ -2675,9 +2684,9 @@ linux_nat_make_corefile_notes (bfd *obfd strncat (psargs, get_inferior_args (), sizeof (psargs) - strlen (psargs)); } - note_data = (char *) elfcore_write_prpsinfo (obfd, - note_data, - note_size, fname, psargs); + note_data = (char *) virtual_elfcore_write_prpsinfo (obfd, note_data, + note_size, fname, + psargs); } /* Dump information for threads. */ Index: gdb/linux-nat.h =================================================================== RCS file: /cvs/src/src/gdb/linux-nat.h,v retrieving revision 1.12 diff -u -p -r1.12 linux-nat.h --- gdb/linux-nat.h 23 Jul 2006 21:21:01 -0000 1.12 +++ gdb/linux-nat.h 28 Sep 2006 15:40:11 -0000 @@ -96,3 +96,12 @@ void linux_nat_add_target (struct target /* Update linux-nat internal state when changing from one fork to another. */ void linux_nat_switch_fork (ptid_t new_ptid); + +/* This functions make elfcore note sections. + They may get overriden by code adjusting data for multi-target builds. */ +extern char *(*virtual_elfcore_write_prpsinfo) + (bfd *, char *, int *, const char *, const char *); +extern char *(*virtual_elfcore_write_prstatus) + (bfd *, char *, int *, long, int, const void *); +extern char *(*virtual_elfcore_write_prfpreg) + (bfd *, char *, int *, const void *, int);