patch-2.1.101 linux/arch/mips/kernel/irixelf.c
Next file: linux/arch/mips/kernel/irixinv.c
Previous file: linux/arch/mips/kernel/irix5sys.h
Back to the patch index
Back to the overall index
- Lines: 231
- Date:
Fri May 8 00:13:23 1998
- Orig file:
v2.1.100/linux/arch/mips/kernel/irixelf.c
- Orig date:
Mon Jan 12 14:52:46 1998
diff -u --recursive --new-file v2.1.100/linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c
@@ -30,6 +30,8 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/mipsregs.h>
+#include <asm/prctl.h>
#include <linux/config.h>
@@ -52,6 +54,11 @@
#endif
};
+#ifndef elf_addr_t
+#define elf_addr_t unsigned long
+#define elf_caddr_t char *
+#endif
+
#ifdef DEBUG_ELF
/* Debugging routines. */
static char *get_elf_p_type(Elf32_Word p_type)
@@ -152,68 +159,67 @@
unsigned int interp_load_addr,
struct pt_regs *regs, struct elf_phdr *ephdr)
{
- char **argv, **envp;
- unsigned long *sp;
- unsigned long *csp;
-
+ elf_caddr_t *argv;
+ elf_caddr_t *envp;
+ elf_addr_t *sp, *csp;
+
#ifdef DEBUG_ELF
printk("create_irix_tables: p[%p] argc[%d] envc[%d] "
"load_addr[%08x] interp_load_addr[%08x]\n",
p, argc, envc, load_addr, interp_load_addr);
#endif
- sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
-
- /* Make sure we will be aligned properly at the end of this. */
+ sp = (elf_addr_t *) (~15UL & (unsigned long) p);
csp = sp;
csp -= exec ? DLINFO_ITEMS*2 : 2;
- csp -= envc + 1;
+ csp -= envc+1;
csp -= argc+1;
- if (!(((unsigned long) csp) & 4))
- sp--;
-
- sp -= exec ? DLINFO_ITEMS*2 : 2;
- sp -= envc+1;
- envp = (char **) sp;
- sp -= argc+1;
- argv = (char **) sp;
-
- __put_user((unsigned long)argc, --sp);
+ csp -= 1; /* argc itself */
+ if ((unsigned long)csp & 15UL) {
+ sp -= (16UL - ((unsigned long)csp & 15UL)) / sizeof(*sp);
+ }
+ /*
+ * Put the ELF interpreter info on the stack
+ */
#define NEW_AUX_ENT(nr, id, val) \
- __put_user ((id), sp+(nr*2)); \
- __put_user ((val), sp+(nr*2+1)); \
+ __put_user ((id), sp+(nr*2)); \
+ __put_user ((val), sp+(nr*2+1)); \
-#define INTERP_ALIGN (~((64 * 1024) - 1))
+ sp -= 2;
+ NEW_AUX_ENT(0, AT_NULL, 0);
- NEW_AUX_ENT (0, AT_NULL, 0);
if(exec) {
- struct elf_phdr * eppnt;
- eppnt = (struct elf_phdr *) exec->e_phoff;
+ sp -= 11*2;
- /* Put this here for an ELF program interpreter */
- NEW_AUX_ENT (0, AT_PHDR, ephdr->p_vaddr);
+ NEW_AUX_ENT (0, AT_PHDR, load_addr + exec->e_phoff);
NEW_AUX_ENT (1, AT_PHENT, sizeof (struct elf_phdr));
NEW_AUX_ENT (2, AT_PHNUM, exec->e_phnum);
- NEW_AUX_ENT (3, AT_PAGESZ, PAGE_SIZE);
- NEW_AUX_ENT (4, AT_BASE, (interp_load_addr & (INTERP_ALIGN)));
+ NEW_AUX_ENT (3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
+ NEW_AUX_ENT (4, AT_BASE, interp_load_addr);
NEW_AUX_ENT (5, AT_FLAGS, 0);
- NEW_AUX_ENT (6, AT_ENTRY, (unsigned long) exec->e_entry);
- NEW_AUX_ENT (7, AT_UID, (unsigned long) current->uid);
- NEW_AUX_ENT (8, AT_EUID, (unsigned long) current->euid);
- NEW_AUX_ENT (9, AT_GID, (unsigned long) current->gid);
- NEW_AUX_ENT (10, AT_EGID, (unsigned long) current->egid);
+ NEW_AUX_ENT (6, AT_ENTRY, (elf_addr_t) exec->e_entry);
+ NEW_AUX_ENT (7, AT_UID, (elf_addr_t) current->uid);
+ NEW_AUX_ENT (8, AT_EUID, (elf_addr_t) current->euid);
+ NEW_AUX_ENT (9, AT_GID, (elf_addr_t) current->gid);
+ NEW_AUX_ENT (10, AT_EGID, (elf_addr_t) current->egid);
}
#undef NEW_AUX_ENT
+ sp -= envc+1;
+ envp = (elf_caddr_t *) sp;
+ sp -= argc+1;
+ argv = (elf_caddr_t *) sp;
+
+ __put_user((elf_addr_t)argc,--sp);
current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
- __put_user(p, argv++);
+ __put_user((elf_caddr_t)(unsigned long)p,argv++);
p += strlen_user(p);
}
__put_user(NULL, argv);
current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
- __put_user(p, envp++);
+ __put_user((elf_caddr_t)(unsigned long)p,envp++);
p += strlen_user(p);
}
__put_user(NULL, envp);
@@ -441,7 +447,8 @@
struct elf_phdr *epp,
struct linux_binprm *bprm, int pnum)
{
- int i, old_fs;
+ mm_segment_t old_fs;
+ int i;
int retval = -EINVAL;
struct dentry *dentry = NULL;
@@ -473,9 +480,8 @@
retval = PTR_ERR(dentry);
goto out;
}
-
retval = read_exec(dentry, 0, bprm->buf, 128, 1);
- if(retval)
+ if(retval < 0)
goto dput_and_out;
*interp_elf_ex = *((struct elfhdr *) bprm->buf);
@@ -546,7 +552,7 @@
static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
struct dentry *identry, unsigned int *iladdr,
- int pnum, int old_fs,
+ int pnum, mm_segment_t old_fs,
unsigned int *eentry)
{
int i;
@@ -573,6 +579,32 @@
return 0;
}
+/*
+ * IRIX maps a page at 0x200000 that holds information about the
+ * process and the system, here we map the page and fill the
+ * structure
+ */
+void irix_map_prda_page (void)
+{
+ unsigned long v;
+ struct prda *pp;
+
+ v = do_mmap (NULL, PRDA_ADDRESS, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE, 0);
+
+ if (v < 0)
+ return;
+
+ pp = (struct prda *) v;
+ pp->prda_sys.t_pid = current->pid;
+ pp->prda_sys.t_prid = read_32bit_cp0_register (CP0_PRID);
+ pp->prda_sys.t_rpid = current->pid;
+
+ /* We leave the rest set to zero */
+}
+
+
+
/* These are the functions used to load ELF style executables and shared
* libraries. There is no binary dependent code anywhere else.
*/
@@ -585,8 +617,9 @@
unsigned int load_addr, elf_bss, elf_brk;
unsigned int elf_entry, interp_load_addr = 0;
unsigned int start_code, end_code, end_data, elf_stack;
- int old_fs, elf_exec_fileno, retval, has_interp, has_ephdr, i;
+ int elf_exec_fileno, retval, has_interp, has_ephdr, i;
char *elf_interpreter;
+ mm_segment_t old_fs;
load_addr = 0;
has_interp = has_ephdr = 0;
@@ -760,6 +793,12 @@
*/
set_brk(elf_bss, elf_brk);
+ /*
+ * IRIX maps a page at 0x200000 which holds some system
+ * information. Programs depend on this.
+ */
+ irix_map_prda_page ();
+
padzero(elf_bss);
#ifdef DEBUG_ELF
@@ -1086,7 +1125,7 @@
struct file file;
struct dentry *dentry;
struct inode *inode;
- unsigned short fs;
+ mm_segment_t fs;
char corefile[6+sizeof(current->comm)];
int segs;
int i;
@@ -1190,8 +1229,8 @@
notes[0].datasz = sizeof(prstatus);
notes[0].data = &prstatus;
prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
- prstatus.pr_sigpend = current->signal;
- prstatus.pr_sighold = current->blocked;
+ prstatus.pr_sigpend = current->signal.sig[0];
+ prstatus.pr_sighold = current->blocked.sig[0];
psinfo.pr_pid = prstatus.pr_pid = current->pid;
psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov