Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[sfrench/cifs-2.6.git] / 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, 2008 David S. Miller (davem@davemloft.net)
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 /* Format is:
13  *      G0 --> G7
14  *      O0 --> O7
15  *      L0 --> L7
16  *      I0 --> I7
17  *      PSR, PC, nPC, Y, WIM, TBR
18  */
19 typedef unsigned int elf_greg_t;
20 #define ELF_NGREG 38
21 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
22
23 typedef struct {
24         union {
25                 unsigned int    pr_regs[32];
26                 unsigned long   pr_dregs[16];
27         } pr_fr;
28         unsigned int __unused;
29         unsigned int    pr_fsr;
30         unsigned char   pr_qcnt;
31         unsigned char   pr_q_entrysize;
32         unsigned char   pr_en;
33         unsigned int    pr_q[64];
34 } elf_fpregset_t;
35
36 /* UltraSparc extensions.  Still unused, but will be eventually.  */
37 typedef struct {
38         unsigned int pr_type;
39         unsigned int pr_align;
40         union {
41                 struct {
42                         union {
43                                 unsigned int    pr_regs[32];
44                                 unsigned long   pr_dregs[16];
45                                 long double     pr_qregs[8];
46                         } pr_xfr;
47                 } pr_v8p;
48                 unsigned int    pr_xfsr;
49                 unsigned int    pr_fprs;
50                 unsigned int    pr_xg[8];
51                 unsigned int    pr_xo[8];
52                 unsigned long   pr_tstate;
53                 unsigned int    pr_filler[8];
54         } pr_un;
55 } elf_xregset_t;
56
57 #define elf_check_arch(x)       (((x)->e_machine == EM_SPARC) || ((x)->e_machine == EM_SPARC32PLUS))
58
59 #define ELF_ET_DYN_BASE         0x70000000
60
61
62 #include <asm/processor.h>
63 #include <linux/module.h>
64 #include <linux/elfcore.h>
65 #include <linux/compat.h>
66
67 #define elf_prstatus elf_prstatus32
68 struct elf_prstatus32
69 {
70         struct elf_siginfo pr_info;     /* Info associated with signal */
71         short   pr_cursig;              /* Current signal */
72         unsigned int pr_sigpend;        /* Set of pending signals */
73         unsigned int pr_sighold;        /* Set of held signals */
74         pid_t   pr_pid;
75         pid_t   pr_ppid;
76         pid_t   pr_pgrp;
77         pid_t   pr_sid;
78         struct compat_timeval pr_utime; /* User time */
79         struct compat_timeval pr_stime; /* System time */
80         struct compat_timeval pr_cutime;        /* Cumulative user time */
81         struct compat_timeval pr_cstime;        /* Cumulative system time */
82         elf_gregset_t pr_reg;   /* GP registers */
83         int pr_fpvalid;         /* True if math co-processor being used.  */
84 };
85
86 #define elf_prpsinfo elf_prpsinfo32
87 struct elf_prpsinfo32
88 {
89         char    pr_state;       /* numeric process state */
90         char    pr_sname;       /* char for pr_state */
91         char    pr_zomb;        /* zombie */
92         char    pr_nice;        /* nice val */
93         unsigned int pr_flag;   /* flags */
94         u16     pr_uid;
95         u16     pr_gid;
96         pid_t   pr_pid, pr_ppid, pr_pgrp, pr_sid;
97         /* Lots missing */
98         char    pr_fname[16];   /* filename of executable */
99         char    pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
100 };
101
102 #include <linux/highuid.h>
103
104 #undef NEW_TO_OLD_UID
105 #undef NEW_TO_OLD_GID
106 #define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
107 #define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
108
109 #include <linux/time.h>
110
111 #undef cputime_to_timeval
112 #define cputime_to_timeval cputime_to_compat_timeval
113 static inline void
114 cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
115 {
116         unsigned long jiffies = cputime_to_jiffies(cputime);
117         value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
118         value->tv_sec = jiffies / HZ;
119 }
120
121 #undef start_thread
122 #define start_thread start_thread32
123 #define init_elf_binfmt init_elf32_binfmt
124
125 MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit SparcLinux binaries on the Ultra");
126 MODULE_AUTHOR("Eric Youngdale, David S. Miller, Jakub Jelinek");
127
128 #undef MODULE_DESCRIPTION
129 #undef MODULE_AUTHOR
130
131 #include <asm/a.out.h>
132
133 #undef TASK_SIZE
134 #define TASK_SIZE STACK_TOP32
135
136 #include "../../../fs/binfmt_elf.c"