Merge branch 'fixes-jgarzik' of git://git.kernel.org/pub/scm/linux/kernel/git/linvill...
[linux-2.6] / arch / sparc64 / kernel / binfmt_elf32.c
1 /*
2  * binfmt_elf32.c: Support 32-bit Sparc ELF binaries on Ultra.
3  *
4  * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
5  * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek   (jj@ultra.linux.cz)
6  */
7
8 #define ELF_ARCH                EM_SPARC
9 #define ELF_CLASS               ELFCLASS32
10 #define ELF_DATA                ELFDATA2MSB;
11
12 /* For the most part we present code dumps in the format
13  * Solaris does.
14  */
15 typedef unsigned int elf_greg_t;
16 #define ELF_NGREG 38
17 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
18
19 /* Format is:
20  *      G0 --> G7
21  *      O0 --> O7
22  *      L0 --> L7
23  *      I0 --> I7
24  *      PSR, PC, nPC, Y, WIM, TBR
25  */
26 #include <asm/psrcompat.h>
27 #define ELF_CORE_COPY_REGS(__elf_regs, __pt_regs)       \
28 do {    unsigned int *dest = &(__elf_regs[0]);          \
29         struct pt_regs *src = (__pt_regs);              \
30         unsigned int __user *sp;                        \
31         int i;                                          \
32         for(i = 0; i < 16; i++)                         \
33                 dest[i] = (unsigned int) src->u_regs[i];\
34         /* Don't try this at home kids... */            \
35         sp = (unsigned int __user *) (src->u_regs[14] & \
36                 0x00000000fffffffc);                    \
37         for(i = 0; i < 16; i++)                         \
38                 __get_user(dest[i+16], &sp[i]);         \
39         dest[32] = tstate_to_psr(src->tstate);          \
40         dest[33] = (unsigned int) src->tpc;             \
41         dest[34] = (unsigned int) src->tnpc;            \
42         dest[35] = src->y;                              \
43         dest[36] = dest[37] = 0; /* XXX */              \
44 } while(0);
45
46 typedef struct {
47         union {
48                 unsigned int    pr_regs[32];
49                 unsigned long   pr_dregs[16];
50         } pr_fr;
51         unsigned int __unused;
52         unsigned int    pr_fsr;
53         unsigned char   pr_qcnt;
54         unsigned char   pr_q_entrysize;
55         unsigned char   pr_en;
56         unsigned int    pr_q[64];
57 } elf_fpregset_t;
58
59 /* UltraSparc extensions.  Still unused, but will be eventually.  */
60 typedef struct {
61         unsigned int pr_type;
62         unsigned int pr_align;
63         union {
64                 struct {
65                         union {
66                                 unsigned int    pr_regs[32];
67                                 unsigned long   pr_dregs[16];
68                                 long double     pr_qregs[8];
69                         } pr_xfr;
70                 } pr_v8p;
71                 unsigned int    pr_xfsr;
72                 unsigned int    pr_fprs;
73                 unsigned int    pr_xg[8];
74                 unsigned int    pr_xo[8];
75                 unsigned long   pr_tstate;
76                 unsigned int    pr_filler[8];
77         } pr_un;
78 } elf_xregset_t;
79
80 #define elf_check_arch(x)       (((x)->e_machine == EM_SPARC) || ((x)->e_machine == EM_SPARC32PLUS))
81
82 #define ELF_ET_DYN_BASE         0x70000000
83
84
85 #include <asm/processor.h>
86 #include <linux/module.h>
87 #include <linux/elfcore.h>
88 #include <linux/compat.h>
89
90 #define elf_prstatus elf_prstatus32
91 struct elf_prstatus32
92 {
93         struct elf_siginfo pr_info;     /* Info associated with signal */
94         short   pr_cursig;              /* Current signal */
95         unsigned int pr_sigpend;        /* Set of pending signals */
96         unsigned int pr_sighold;        /* Set of held signals */
97         pid_t   pr_pid;
98         pid_t   pr_ppid;
99         pid_t   pr_pgrp;
100         pid_t   pr_sid;
101         struct compat_timeval pr_utime; /* User time */
102         struct compat_timeval pr_stime; /* System time */
103         struct compat_timeval pr_cutime;        /* Cumulative user time */
104         struct compat_timeval pr_cstime;        /* Cumulative system time */
105         elf_gregset_t pr_reg;   /* GP registers */
106         int pr_fpvalid;         /* True if math co-processor being used.  */
107 };
108
109 #define elf_prpsinfo elf_prpsinfo32
110 struct elf_prpsinfo32
111 {
112         char    pr_state;       /* numeric process state */
113         char    pr_sname;       /* char for pr_state */
114         char    pr_zomb;        /* zombie */
115         char    pr_nice;        /* nice val */
116         unsigned int pr_flag;   /* flags */
117         u16     pr_uid;
118         u16     pr_gid;
119         pid_t   pr_pid, pr_ppid, pr_pgrp, pr_sid;
120         /* Lots missing */
121         char    pr_fname[16];   /* filename of executable */
122         char    pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
123 };
124
125 #include <linux/highuid.h>
126
127 #undef NEW_TO_OLD_UID
128 #undef NEW_TO_OLD_GID
129 #define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
130 #define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
131
132 #include <linux/time.h>
133
134 #undef cputime_to_timeval
135 #define cputime_to_timeval cputime_to_compat_timeval
136 static __inline__ void
137 cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
138 {
139         unsigned long jiffies = cputime_to_jiffies(cputime);
140         value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
141         value->tv_sec = jiffies / HZ;
142 }
143
144 #undef start_thread
145 #define start_thread start_thread32
146 #define init_elf_binfmt init_elf32_binfmt
147
148 MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit SparcLinux binaries on the Ultra");
149 MODULE_AUTHOR("Eric Youngdale, David S. Miller, Jakub Jelinek");
150
151 #undef MODULE_DESCRIPTION
152 #undef MODULE_AUTHOR
153
154 #include <asm/a.out.h>
155
156 #undef TASK_SIZE
157 #define TASK_SIZE STACK_TOP32
158
159 #include "../../../fs/binfmt_elf.c"