2 * Support for 32-bit Linux for S390 ELF binaries.
4 * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Gerhard Tonn (ton@de.ibm.com)
7 * Heavily inspired by the 32-bit Sparc compat code which is
8 * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
9 * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz)
13 #define __ASMS390_ELF_H
16 * These are used to set parameters in the core dumps.
18 #define ELF_CLASS ELFCLASS32
19 #define ELF_DATA ELFDATA2MSB
20 #define ELF_ARCH EM_S390
23 * This is used to ensure we don't load something for the wrong architecture.
25 #define elf_check_arch(x) \
26 (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \
27 && (x)->e_ident[EI_CLASS] == ELF_CLASS)
29 /* ELF register definitions */
34 #define TASK31_SIZE (0x80000000UL)
36 /* For SVR4/S390 the function pointer to be registered with `atexit` is
38 #define ELF_PLAT_INIT(_r, load_addr) \
41 current->thread.flags |= S390_FLAG_31BIT; \
44 #define USE_ELF_CORE_DUMP
45 #define ELF_EXEC_PAGESIZE 4096
47 /* This is the location that an ET_DYN program is loaded if exec'ed. Typical
48 use of this is to invoke "./ld.so someprog" to test out a new version of
49 the loader. We need to make sure that it is out of the way of the program
50 that it will "exec", and that there is sufficient room for the brk. */
52 #define ELF_ET_DYN_BASE ((TASK31_SIZE & 0x80000000) \
53 ? TASK31_SIZE / 3 * 2 \
54 : 2 * TASK31_SIZE / 3)
56 /* Wow, the "main" arch needs arch dependent functions too.. :) */
58 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
59 now struct_user_regs, they are different) */
61 #define ELF_CORE_COPY_REGS(pr_reg, regs) \
64 memcpy(&pr_reg.psw.mask, ®s->psw.mask, 4); \
65 memcpy(&pr_reg.psw.addr, ((char*)®s->psw.addr)+4, 4); \
66 for(i=0; i<NUM_GPRS; i++) \
67 pr_reg.gprs[i] = regs->gprs[i]; \
68 for(i=0; i<NUM_ACRS; i++) \
69 pr_reg.acrs[i] = regs->acrs[i]; \
70 pr_reg.orig_gpr2 = regs->orig_gpr2; \
75 /* This yields a mask that user programs can use to figure out what
76 instruction set this CPU supports. */
80 /* This yields a string that ld.so will use to load implementation
81 specific libraries for optimization. This is more specific in
82 intent than poking at uname or /proc/cpuinfo.
84 For the moment, we have only optimizations for the Intel generations,
85 but that could change... */
87 #define ELF_PLATFORM (NULL)
90 #define SET_PERSONALITY(ex, ibcs2) \
93 set_personality(PER_SVR4); \
94 else if (current->personality != PER_LINUX32) \
95 set_personality(PER_LINUX); \
101 typedef _s390_fp_regs32 elf_fpregset_t;
107 __u32 gprs[__NUM_GPRS];
108 __u32 acrs[__NUM_ACRS];
111 typedef s390_regs32 elf_gregset_t;
113 #include <asm/processor.h>
114 #include <linux/module.h>
115 #include <linux/config.h>
116 #include <linux/elfcore.h>
118 int setup_arg_pages32(struct linux_binprm *bprm);
125 #define elf_prstatus elf_prstatus32
126 struct elf_prstatus32
128 struct elf_siginfo pr_info; /* Info associated with signal */
129 short pr_cursig; /* Current signal */
130 u32 pr_sigpend; /* Set of pending signals */
131 u32 pr_sighold; /* Set of held signals */
136 struct timeval32 pr_utime; /* User time */
137 struct timeval32 pr_stime; /* System time */
138 struct timeval32 pr_cutime; /* Cumulative user time */
139 struct timeval32 pr_cstime; /* Cumulative system time */
140 elf_gregset_t pr_reg; /* GP registers */
141 int pr_fpvalid; /* True if math co-processor being used. */
144 #define elf_prpsinfo elf_prpsinfo32
145 struct elf_prpsinfo32
147 char pr_state; /* numeric process state */
148 char pr_sname; /* char for pr_state */
149 char pr_zomb; /* zombie */
150 char pr_nice; /* nice val */
151 u32 pr_flag; /* flags */
154 pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
156 char pr_fname[16]; /* filename of executable */
157 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
160 #include <linux/highuid.h>
162 #undef NEW_TO_OLD_UID
163 #undef NEW_TO_OLD_GID
164 #define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
165 #define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
167 #define elf_addr_t u32
168 #define elf_caddr_t u32
170 #define init_elf_binfmt init_elf32_binfmt
172 #undef CONFIG_BINFMT_ELF
173 #ifdef CONFIG_BINFMT_ELF32
174 #define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32
176 #undef CONFIG_BINFMT_ELF_MODULE
177 #ifdef CONFIG_BINFMT_ELF32_MODULE
178 #define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE
182 #define start_thread start_thread31
183 #define setup_arg_pages(bprm) setup_arg_pages32(bprm)
184 #define elf_map elf_map32
186 MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux for S390 binaries,"
187 " Copyright 2000 IBM Corporation");
188 MODULE_AUTHOR("Gerhard Tonn <ton@de.ibm.com>");
190 #undef MODULE_DESCRIPTION
193 #include "../../../fs/binfmt_elf.c"
196 elf_map32 (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
198 unsigned long map_addr;
203 down_write(¤t->mm->mmap_sem);
204 map_addr = do_mmap(filep, ELF_PAGESTART(addr),
205 eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
206 eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
207 up_write(¤t->mm->mmap_sem);