]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] ia64: make ia32 core dumps work
authorArun Sharma <arun.sharma@intel.com>
Thu, 7 Aug 2003 06:22:58 +0000 (23:22 -0700)
committerDavid Mosberger <davidm@tiger.hpl.hp.com>
Thu, 7 Aug 2003 06:22:58 +0000 (23:22 -0700)
The attached patch implements core dump functionality for IA-32
applications running on ia64.

arch/ia64/ia32/binfmt_elf32.c
arch/ia64/ia32/elfcore32.h [new file with mode: 0644]
arch/ia64/ia32/ia32priv.h
arch/ia64/ia32/sys_ia32.c

index 8b2a41592746e8624adf811e4ee207b19e69989a..000a94b3ee810a825580148b0a1f1e588acceae0 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/signal.h>
 
 #include "ia32priv.h"
+#include "elfcore32.h"
 
 #define CONFIG_BINFMT_ELF32
 
diff --git a/arch/ia64/ia32/elfcore32.h b/arch/ia64/ia32/elfcore32.h
new file mode 100644 (file)
index 0000000..60b80af
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * IA-32 ELF core dump support.
+ *
+ * Copyright (C) 2003 Arun Sharma <arun.sharma@intel.com>
+ *
+ * Derived from the x86_64 version
+ */
+#ifndef _ELFCORE32_H_
+#define _ELFCORE32_H_
+
+#define USE_ELF_CORE_DUMP 1
+
+/* Override elfcore.h */
+#define _LINUX_ELFCORE_H 1
+typedef unsigned int elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct ia32_user_i387_struct elf_fpregset_t;
+typedef struct ia32_user_fxsr_struct elf_fpxregset_t;
+
+struct elf_siginfo
+{
+       int     si_signo;                       /* signal number */
+       int     si_code;                        /* extra code */
+       int     si_errno;                       /* errno */
+};
+
+#define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
+
+struct elf_prstatus
+{
+       struct elf_siginfo pr_info;     /* Info associated with signal */
+       short   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 compat_timeval pr_utime; /* User time */
+       struct compat_timeval pr_stime; /* System time */
+       struct compat_timeval pr_cutime;        /* Cumulative user time */
+       struct compat_timeval pr_cstime;        /* Cumulative system time */
+       elf_gregset_t pr_reg;   /* GP registers */
+       int pr_fpvalid;         /* True if math co-processor being used.  */
+};
+
+#define ELF_PRARGSZ    (80)    /* Number of chars for args */
+
+struct elf_prpsinfo
+{
+       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 */
+       __u16   pr_uid;
+       __u16   pr_gid;
+       pid_t   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 */
+};
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)                       \
+       pr_reg[0] = regs->r11;                          \
+       pr_reg[1] = regs->r9;                           \
+       pr_reg[2] = regs->r10;                          \
+       pr_reg[3] = regs->r14;                          \
+       pr_reg[4] = regs->r15;                          \
+       pr_reg[5] = regs->r13;                          \
+       pr_reg[6] = regs->r8;                           \
+       pr_reg[7] = regs->r16 & 0xffff;                 \
+       pr_reg[8] = (regs->r16 >> 16) & 0xffff;         \
+       pr_reg[9] = (regs->r16 >> 32) & 0xffff;         \
+       pr_reg[10] = (regs->r16 >> 48) & 0xffff;        \
+       pr_reg[11] = regs->r1;                          \
+       pr_reg[12] = regs->cr_iip;                      \
+       pr_reg[13] = regs->r17 & 0xffff;                \
+       asm volatile ("mov %0=ar.eflag ;;"              \
+                     : "=r"(pr_reg[14]));              \
+       pr_reg[15] = regs->r12;                         \
+       pr_reg[16] = (regs->r17 >> 16) & 0xffff;
+
+static inline void elf_core_copy_regs(elf_gregset_t *elfregs,
+                                     struct pt_regs *regs)
+{
+       ELF_CORE_COPY_REGS((*elfregs), regs)
+}
+
+static inline int elf_core_copy_task_regs(struct task_struct *t,
+                                         elf_gregset_t* elfregs)
+{
+       struct pt_regs *pp = ia64_task_regs(t);
+       ELF_CORE_COPY_REGS((*elfregs), pp);
+       return 1;
+}
+
+static inline int
+elf_core_copy_task_fpregs(struct task_struct *tsk, elf_fpregset_t *fpu)
+{
+       struct ia32_user_i387_struct *fpstate = (void*)fpu;
+
+       if (!tsk->used_math)
+               return 0;
+
+       save_ia32_fpstate(tsk, fpstate);
+
+       return 1;
+}
+
+#define ELF_CORE_COPY_XFPREGS 1
+static inline int
+elf_core_copy_task_xfpregs(struct task_struct *tsk, elf_fpxregset_t *xfpu)
+{
+       struct ia32_user_fxsr_struct *fpxstate = (void*) xfpu;
+
+       if (!tsk->used_math)
+               return 0;
+
+       save_ia32_fpxstate(tsk, fpxstate);
+
+       return 1;
+}
+
+#endif /* _ELFCORE32_H_ */
index d9537ba7f047a47d22719a5f38616c75d4844046..e830969c84ea8f90efae932dfdaa33cbbc5e91a5 100644 (file)
@@ -295,7 +295,6 @@ struct old_linux32_dirent {
 #define IA32_TSS_OFFSET                (IA32_PAGE_OFFSET + PAGE_SIZE)
 #define IA32_LDT_OFFSET                (IA32_PAGE_OFFSET + 2*PAGE_SIZE)
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE      IA32_PAGE_SIZE
 
 /*
@@ -312,20 +311,6 @@ void ia64_elf32_init(struct pt_regs *regs);
 
 #define elf_addr_t     u32
 
-/* ELF register definitions.  This is needed for core dump support.  */
-
-#define ELF_NGREG      128                     /* XXX fix me */
-#define ELF_NFPREG     128                     /* XXX fix me */
-
-typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct {
-       unsigned long w0;
-       unsigned long w1;
-} elf_fpreg_t;
-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-
 /* This macro yields a bitmask that programs can use to figure out
    what instruction set this CPU supports.  */
 #define ELF_HWCAP      0
@@ -472,6 +457,23 @@ extern void ia32_load_segment_descriptors (struct task_struct *task);
        asm volatile ("ldf.fill f6=[%2];; stfe [%1]=f6" : "=f"(f6): "r"(dst),  "r"(src) : "memory"); \
        } while(0)
 
+struct user_regs_struct32 {
+       __u32 ebx, ecx, edx, esi, edi, ebp, eax;
+       unsigned short ds, __ds, es, __es;
+       unsigned short fs, __fs, gs, __gs;
+       __u32 orig_eax, eip;
+       unsigned short cs, __cs;
+       __u32 eflags, esp;
+       unsigned short ss, __ss;
+};
+
+/* Prototypes for use in elfcore32.h */
+int save_ia32_fpstate (struct task_struct *tsk,
+                       struct ia32_user_i387_struct *save);
+
+int save_ia32_fpxstate (struct task_struct *tsk,
+                       struct ia32_user_fxsr_struct *save);
+
 #endif /* !CONFIG_IA32_SUPPORT */
 
 #endif /* _ASM_IA64_IA32_H */
index d778e4d6cc7cdecce2ad1b33e1d6946a49ef7ff7..8d7fd9458f34139f2fc1866e220b4aa2b4926f56 100644 (file)
@@ -1866,7 +1866,7 @@ get_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switc
        return;
 }
 
-static int
+int
 save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save)
 {
        struct switch_stack *swp;
@@ -1928,7 +1928,7 @@ restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *sav
        return 0;
 }
 
-static int
+int
 save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save)
 {
        struct switch_stack *swp;