1/* 2 * Support for 32-bit Linux for S390 ELF binaries. 3 * 4 * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Author(s): Gerhard Tonn (ton@de.ibm.com) 6 * 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) 10 */ 11 12 13#define __ASMS390_ELF_H 14 15/* 16 * These are used to set parameters in the core dumps. 17 */ 18#define ELF_CLASS ELFCLASS32 19#define ELF_DATA ELFDATA2MSB 20#define ELF_ARCH EM_S390 21 22/* 23 * This is used to ensure we don't load something for the wrong architecture. 24 */ 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) 28 29/* ELF register definitions */ 30#define NUM_GPRS 16 31#define NUM_FPRS 16 32#define NUM_ACRS 16 33 34#define TASK31_SIZE (0x80000000UL) 35 36/* For SVR4/S390 the function pointer to be registered with `atexit` is 37 passed in R14. */ 38#define ELF_PLAT_INIT(_r) \ 39 do { \ 40 _r->gprs[14] = 0; \ 41 current->thread.flags |= S390_FLAG_31BIT; \ 42 } while(0) 43 44#define USE_ELF_CORE_DUMP 45#define ELF_EXEC_PAGESIZE 4096 46 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. */ 51 52#define ELF_ET_DYN_BASE ((TASK31_SIZE & 0x80000000) \ 53 ? TASK31_SIZE / 3 * 2 \ 54 : 2 * TASK31_SIZE / 3) 55 56/* Wow, the "main" arch needs arch dependent functions too.. :) */ 57 58/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is 59 now struct_user_regs, they are different) */ 60 61#define ELF_CORE_COPY_REGS(pr_reg, regs) \ 62 { \ 63 int i; \ 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; \ 71 } 72 73 74 75/* This yields a mask that user programs can use to figure out what 76 instruction set this CPU supports. */ 77 78#define ELF_HWCAP (0) 79 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. 83 84 For the moment, we have only optimizations for the Intel generations, 85 but that could change... */ 86 87#define ELF_PLATFORM (NULL) 88 89#ifdef __KERNEL__ 90#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) 91#endif 92 93#include "linux32.h" 94 95typedef _s390_fp_regs32 elf_fpregset_t; 96 97typedef struct 98{ 99 100 _psw_t32 psw; 101 __u32 gprs[__NUM_GPRS]; 102 __u32 acrs[__NUM_ACRS]; 103 __u32 orig_gpr2; 104} s390_regs32; 105typedef s390_regs32 elf_gregset_t; 106 107#include <asm/processor.h> 108#include <linux/module.h> 109#include <linux/config.h> 110#include <linux/elfcore.h> 111 112int setup_arg_pages32(struct linux_binprm *bprm); 113 114struct timeval32 115{ 116 int tv_sec, tv_usec; 117}; 118 119#define elf_prstatus elf_prstatus32 120struct elf_prstatus32 121{ 122 struct elf_siginfo pr_info; /* Info associated with signal */ 123 short pr_cursig; /* Current signal */ 124 u32 pr_sigpend; /* Set of pending signals */ 125 u32 pr_sighold; /* Set of held signals */ 126 pid_t pr_pid; 127 pid_t pr_ppid; 128 pid_t pr_pgrp; 129 pid_t pr_sid; 130 struct timeval32 pr_utime; /* User time */ 131 struct timeval32 pr_stime; /* System time */ 132 struct timeval32 pr_cutime; /* Cumulative user time */ 133 struct timeval32 pr_cstime; /* Cumulative system time */ 134 elf_gregset_t pr_reg; /* GP registers */ 135 int pr_fpvalid; /* True if math co-processor being used. */ 136}; 137 138#define elf_prpsinfo elf_prpsinfo32 139struct elf_prpsinfo32 140{ 141 char pr_state; /* numeric process state */ 142 char pr_sname; /* char for pr_state */ 143 char pr_zomb; /* zombie */ 144 char pr_nice; /* nice val */ 145 u32 pr_flag; /* flags */ 146 u16 pr_uid; 147 u16 pr_gid; 148 pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; 149 /* Lots missing */ 150 char pr_fname[16]; /* filename of executable */ 151 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ 152}; 153 154#include <linux/highuid.h> 155 156#undef NEW_TO_OLD_UID 157#undef NEW_TO_OLD_GID 158#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) 159#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) 160 161#define elf_addr_t u32 162#define elf_caddr_t u32 163/* 164#define init_elf_binfmt init_elf32_binfmt 165*/ 166#undef CONFIG_BINFMT_ELF 167#ifdef CONFIG_BINFMT_ELF32 168#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 169#endif 170#undef CONFIG_BINFMT_ELF_MODULE 171#ifdef CONFIG_BINFMT_ELF32_MODULE 172#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE 173#endif 174 175#undef start_thread 176#define start_thread start_thread31 177#define setup_arg_pages(bprm) setup_arg_pages32(bprm) 178#define elf_map elf_map32 179 180MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux for S390 binaries," 181 " Copyright 2000 IBM Corporation"); 182MODULE_AUTHOR("Gerhard Tonn <ton@de.ibm.com>"); 183 184#undef MODULE_DESCRIPTION 185#undef MODULE_AUTHOR 186 187#include "../../../fs/binfmt_elf.c" 188 189static unsigned long 190elf_map32 (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) 191{ 192 unsigned long map_addr; 193 194 if(!addr) 195 addr = 0x40000000; 196 197 down_write(¤t->mm->mmap_sem); 198 map_addr = do_mmap(filep, ELF_PAGESTART(addr), 199 eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type, 200 eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr)); 201 up_write(¤t->mm->mmap_sem); 202 return(map_addr); 203} 204 205