···11-/*22- * This file is subject to the terms and conditions of the GNU General Public33- * License. See the file "COPYING" in the main directory of this archive44- * for more details.55- *66- * irixelf.c: Code to load IRIX ELF executables conforming to the MIPS ABI.77- * Based off of work by Eric Youngdale.88- *99- * Copyright (C) 1993 - 1994 Eric Youngdale <ericy@cais.com>1010- * Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>1111- * Copyright (C) 2004 - 2005 Steven J. Hill <sjhill@realitydiluted.com>1212- */1313-#undef DEBUG1414-1515-#include <linux/module.h>1616-#include <linux/fs.h>1717-#include <linux/stat.h>1818-#include <linux/sched.h>1919-#include <linux/mm.h>2020-#include <linux/mman.h>2121-#include <linux/a.out.h>2222-#include <linux/errno.h>2323-#include <linux/init.h>2424-#include <linux/signal.h>2525-#include <linux/binfmts.h>2626-#include <linux/string.h>2727-#include <linux/file.h>2828-#include <linux/fcntl.h>2929-#include <linux/ptrace.h>3030-#include <linux/slab.h>3131-#include <linux/shm.h>3232-#include <linux/personality.h>3333-#include <linux/elfcore.h>3434-3535-#include <asm/mipsregs.h>3636-#include <asm/namei.h>3737-#include <asm/prctl.h>3838-#include <asm/uaccess.h>3939-4040-#define DLINFO_ITEMS 124141-4242-#include <linux/elf.h>4343-4444-static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);4545-static int load_irix_library(struct file *);4646-static int irix_core_dump(long signr, struct pt_regs * regs,4747- struct file *file, unsigned long limit);4848-4949-static struct linux_binfmt irix_format = {5050- .module = THIS_MODULE,5151- .load_binary = load_irix_binary,5252- .load_shlib = load_irix_library,5353- .core_dump = irix_core_dump,5454- .min_coredump = PAGE_SIZE,5555-};5656-5757-/* Debugging routines. */5858-static char *get_elf_p_type(Elf32_Word p_type)5959-{6060-#ifdef DEBUG6161- switch (p_type) {6262- case PT_NULL:6363- return "PT_NULL";6464- break;6565-6666- case PT_LOAD:6767- return "PT_LOAD";6868- break;6969-7070- case PT_DYNAMIC:7171- return "PT_DYNAMIC";7272- break;7373-7474- case PT_INTERP:7575- return "PT_INTERP";7676- break;7777-7878- case PT_NOTE:7979- return "PT_NOTE";8080- break;8181-8282- case PT_SHLIB:8383- return "PT_SHLIB";8484- break;8585-8686- case PT_PHDR:8787- return "PT_PHDR";8888- break;8989-9090- case PT_LOPROC:9191- return "PT_LOPROC/REGINFO";9292- break;9393-9494- case PT_HIPROC:9595- return "PT_HIPROC";9696- break;9797-9898- default:9999- return "PT_BOGUS";100100- break;101101- }102102-#endif103103-}104104-105105-static void print_elfhdr(struct elfhdr *ehp)106106-{107107- int i;108108-109109- pr_debug("ELFHDR: e_ident<");110110- for (i = 0; i < (EI_NIDENT - 1); i++)111111- pr_debug("%x ", ehp->e_ident[i]);112112- pr_debug("%x>\n", ehp->e_ident[i]);113113- pr_debug(" e_type[%04x] e_machine[%04x] e_version[%08lx]\n",114114- (unsigned short) ehp->e_type, (unsigned short) ehp->e_machine,115115- (unsigned long) ehp->e_version);116116- pr_debug(" e_entry[%08lx] e_phoff[%08lx] e_shoff[%08lx] "117117- "e_flags[%08lx]\n",118118- (unsigned long) ehp->e_entry, (unsigned long) ehp->e_phoff,119119- (unsigned long) ehp->e_shoff, (unsigned long) ehp->e_flags);120120- pr_debug(" e_ehsize[%04x] e_phentsize[%04x] e_phnum[%04x]\n",121121- (unsigned short) ehp->e_ehsize,122122- (unsigned short) ehp->e_phentsize,123123- (unsigned short) ehp->e_phnum);124124- pr_debug(" e_shentsize[%04x] e_shnum[%04x] e_shstrndx[%04x]\n",125125- (unsigned short) ehp->e_shentsize,126126- (unsigned short) ehp->e_shnum,127127- (unsigned short) ehp->e_shstrndx);128128-}129129-130130-static void print_phdr(int i, struct elf_phdr *ep)131131-{132132- pr_debug("PHDR[%d]: p_type[%s] p_offset[%08lx] p_vaddr[%08lx] "133133- "p_paddr[%08lx]\n", i, get_elf_p_type(ep->p_type),134134- (unsigned long) ep->p_offset, (unsigned long) ep->p_vaddr,135135- (unsigned long) ep->p_paddr);136136- pr_debug(" p_filesz[%08lx] p_memsz[%08lx] p_flags[%08lx] "137137- "p_align[%08lx]\n", (unsigned long) ep->p_filesz,138138- (unsigned long) ep->p_memsz, (unsigned long) ep->p_flags,139139- (unsigned long) ep->p_align);140140-}141141-142142-static void dump_phdrs(struct elf_phdr *ep, int pnum)143143-{144144- int i;145145-146146- for (i = 0; i < pnum; i++, ep++) {147147- if ((ep->p_type == PT_LOAD) ||148148- (ep->p_type == PT_INTERP) ||149149- (ep->p_type == PT_PHDR))150150- print_phdr(i, ep);151151- }152152-}153153-154154-static void set_brk(unsigned long start, unsigned long end)155155-{156156- start = PAGE_ALIGN(start);157157- end = PAGE_ALIGN(end);158158- if (end <= start)159159- return;160160- down_write(¤t->mm->mmap_sem);161161- do_brk(start, end - start);162162- up_write(¤t->mm->mmap_sem);163163-}164164-165165-166166-/* We need to explicitly zero any fractional pages167167- * after the data section (i.e. bss). This would168168- * contain the junk from the file that should not169169- * be in memory.170170- */171171-static void padzero(unsigned long elf_bss)172172-{173173- unsigned long nbyte;174174-175175- nbyte = elf_bss & (PAGE_SIZE-1);176176- if (nbyte) {177177- nbyte = PAGE_SIZE - nbyte;178178- clear_user((void __user *) elf_bss, nbyte);179179- }180180-}181181-182182-static unsigned long * create_irix_tables(char * p, int argc, int envc,183183- struct elfhdr * exec, unsigned int load_addr,184184- unsigned int interp_load_addr, struct pt_regs *regs,185185- struct elf_phdr *ephdr)186186-{187187- elf_addr_t *argv;188188- elf_addr_t *envp;189189- elf_addr_t *sp, *csp;190190-191191- pr_debug("create_irix_tables: p[%p] argc[%d] envc[%d] "192192- "load_addr[%08x] interp_load_addr[%08x]\n",193193- p, argc, envc, load_addr, interp_load_addr);194194-195195- sp = (elf_addr_t *) (~15UL & (unsigned long) p);196196- csp = sp;197197- csp -= exec ? DLINFO_ITEMS*2 : 2;198198- csp -= envc+1;199199- csp -= argc+1;200200- csp -= 1; /* argc itself */201201- if ((unsigned long)csp & 15UL) {202202- sp -= (16UL - ((unsigned long)csp & 15UL)) / sizeof(*sp);203203- }204204-205205- /*206206- * Put the ELF interpreter info on the stack207207- */208208-#define NEW_AUX_ENT(nr, id, val) \209209- __put_user((id), sp+(nr*2)); \210210- __put_user((val), sp+(nr*2+1)); \211211-212212- sp -= 2;213213- NEW_AUX_ENT(0, AT_NULL, 0);214214-215215- if (exec) {216216- sp -= 11*2;217217-218218- NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);219219- NEW_AUX_ENT(1, AT_PHENT, sizeof(struct elf_phdr));220220- NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);221221- NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE);222222- NEW_AUX_ENT(4, AT_BASE, interp_load_addr);223223- NEW_AUX_ENT(5, AT_FLAGS, 0);224224- NEW_AUX_ENT(6, AT_ENTRY, (elf_addr_t) exec->e_entry);225225- NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid);226226- NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid);227227- NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid);228228- NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid);229229- }230230-#undef NEW_AUX_ENT231231-232232- sp -= envc+1;233233- envp = sp;234234- sp -= argc+1;235235- argv = sp;236236-237237- __put_user((elf_addr_t)argc, --sp);238238- current->mm->arg_start = (unsigned long) p;239239- while (argc-->0) {240240- __put_user((unsigned long)p, argv++);241241- p += strlen_user(p);242242- }243243- __put_user((unsigned long) NULL, argv);244244- current->mm->arg_end = current->mm->env_start = (unsigned long) p;245245- while (envc-->0) {246246- __put_user((unsigned long)p, envp++);247247- p += strlen_user(p);248248- }249249- __put_user((unsigned long) NULL, envp);250250- current->mm->env_end = (unsigned long) p;251251- return sp;252252-}253253-254254-255255-/* This is much more generalized than the library routine read function,256256- * so we keep this separate. Technically the library read function257257- * is only provided so that we can read a.out libraries that have258258- * an ELF header.259259- */260260-static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,261261- struct file * interpreter,262262- unsigned int *interp_load_addr)263263-{264264- struct elf_phdr *elf_phdata = NULL;265265- struct elf_phdr *eppnt;266266- unsigned int len;267267- unsigned int load_addr;268268- int elf_bss;269269- int retval;270270- unsigned int last_bss;271271- int error;272272- int i;273273- unsigned int k;274274-275275- elf_bss = 0;276276- last_bss = 0;277277- error = load_addr = 0;278278-279279- print_elfhdr(interp_elf_ex);280280-281281- /* First of all, some simple consistency checks */282282- if ((interp_elf_ex->e_type != ET_EXEC &&283283- interp_elf_ex->e_type != ET_DYN) ||284284- !interpreter->f_op->mmap) {285285- printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);286286- return 0xffffffff;287287- }288288-289289- /* Now read in all of the header information */290290- if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE) {291291- printk("IRIX interp header bigger than a page (%d)\n",292292- (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum));293293- return 0xffffffff;294294- }295295-296296- elf_phdata = kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum,297297- GFP_KERNEL);298298-299299- if (!elf_phdata) {300300- printk("Cannot kmalloc phdata for IRIX interp.\n");301301- return 0xffffffff;302302- }303303-304304- /* If the size of this structure has changed, then punt, since305305- * we will be doing the wrong thing.306306- */307307- if (interp_elf_ex->e_phentsize != 32) {308308- printk("IRIX interp e_phentsize == %d != 32 ",309309- interp_elf_ex->e_phentsize);310310- kfree(elf_phdata);311311- return 0xffffffff;312312- }313313-314314- retval = kernel_read(interpreter, interp_elf_ex->e_phoff,315315- (char *) elf_phdata,316316- sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);317317-318318- dump_phdrs(elf_phdata, interp_elf_ex->e_phnum);319319-320320- eppnt = elf_phdata;321321- for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {322322- if (eppnt->p_type == PT_LOAD) {323323- int elf_type = MAP_PRIVATE | MAP_DENYWRITE;324324- int elf_prot = 0;325325- unsigned long vaddr = 0;326326- if (eppnt->p_flags & PF_R)327327- elf_prot = PROT_READ;328328- if (eppnt->p_flags & PF_W)329329- elf_prot |= PROT_WRITE;330330- if (eppnt->p_flags & PF_X)331331- elf_prot |= PROT_EXEC;332332- elf_type |= MAP_FIXED;333333- vaddr = eppnt->p_vaddr;334334-335335- pr_debug("INTERP do_mmap"336336- "(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",337337- interpreter, vaddr,338338- (unsigned long)339339- (eppnt->p_filesz + (eppnt->p_vaddr & 0xfff)),340340- (unsigned long)341341- elf_prot, (unsigned long) elf_type,342342- (unsigned long)343343- (eppnt->p_offset & 0xfffff000));344344-345345- down_write(¤t->mm->mmap_sem);346346- error = do_mmap(interpreter, vaddr,347347- eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),348348- elf_prot, elf_type,349349- eppnt->p_offset & 0xfffff000);350350- up_write(¤t->mm->mmap_sem);351351-352352- if (error < 0 && error > -1024) {353353- printk("Aieee IRIX interp mmap error=%d\n",354354- error);355355- break; /* Real error */356356- }357357- pr_debug("error=%08lx ", (unsigned long) error);358358- if (!load_addr && interp_elf_ex->e_type == ET_DYN) {359359- load_addr = error;360360- pr_debug("load_addr = error ");361361- }362362-363363- /*364364- * Find the end of the file mapping for this phdr, and365365- * keep track of the largest address we see for this.366366- */367367- k = eppnt->p_vaddr + eppnt->p_filesz;368368- if (k > elf_bss)369369- elf_bss = k;370370-371371- /* Do the same thing for the memory mapping - between372372- * elf_bss and last_bss is the bss section.373373- */374374- k = eppnt->p_memsz + eppnt->p_vaddr;375375- if (k > last_bss)376376- last_bss = k;377377- pr_debug("\n");378378- }379379- }380380-381381- /* Now use mmap to map the library into memory. */382382- if (error < 0 && error > -1024) {383383- pr_debug("got error %d\n", error);384384- kfree(elf_phdata);385385- return 0xffffffff;386386- }387387-388388- /* Now fill out the bss section. First pad the last page up389389- * to the page boundary, and then perform a mmap to make sure390390- * that there are zero-mapped pages up to and including the391391- * last bss page.392392- */393393- pr_debug("padzero(%08lx) ", (unsigned long) (elf_bss));394394- padzero(elf_bss);395395- len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */396396-397397- pr_debug("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,398398- (unsigned long) len);399399-400400- /* Map the last of the bss segment */401401- if (last_bss > len) {402402- down_write(¤t->mm->mmap_sem);403403- do_brk(len, (last_bss - len));404404- up_write(¤t->mm->mmap_sem);405405- }406406- kfree(elf_phdata);407407-408408- *interp_load_addr = load_addr;409409- return ((unsigned int) interp_elf_ex->e_entry);410410-}411411-412412-/* Check sanity of IRIX elf executable header. */413413-static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)414414-{415415- if (memcmp(ehp->e_ident, ELFMAG, SELFMAG) != 0)416416- return -ENOEXEC;417417-418418- /* First of all, some simple consistency checks */419419- if ((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||420420- !bprm->file->f_op->mmap) {421421- return -ENOEXEC;422422- }423423-424424- /* XXX Don't support N32 or 64bit binaries yet because they can425425- * XXX and do execute 64 bit instructions and expect all registers426426- * XXX to be 64 bit as well. We need to make the kernel save427427- * XXX all registers as 64bits on cpu's capable of this at428428- * XXX exception time plus frob the XTLB exception vector.429429- */430430- if ((ehp->e_flags & EF_MIPS_ABI2))431431- return -ENOEXEC;432432-433433- return 0;434434-}435435-436436-/*437437- * This is where the detailed check is performed. Irix binaries438438- * use interpreters with 'libc.so' in the name, so this function439439- * can differentiate between Linux and Irix binaries.440440- */441441-static inline int look_for_irix_interpreter(char **name,442442- struct file **interpreter,443443- struct elfhdr *interp_elf_ex,444444- struct elf_phdr *epp,445445- struct linux_binprm *bprm, int pnum)446446-{447447- int i;448448- int retval = -EINVAL;449449- struct file *file = NULL;450450-451451- *name = NULL;452452- for (i = 0; i < pnum; i++, epp++) {453453- if (epp->p_type != PT_INTERP)454454- continue;455455-456456- /* It is illegal to have two interpreters for one executable. */457457- if (*name != NULL)458458- goto out;459459-460460- *name = kmalloc(epp->p_filesz + strlen(IRIX_EMUL), GFP_KERNEL);461461- if (!*name)462462- return -ENOMEM;463463-464464- strcpy(*name, IRIX_EMUL);465465- retval = kernel_read(bprm->file, epp->p_offset, (*name + 16),466466- epp->p_filesz);467467- if (retval < 0)468468- goto out;469469-470470- file = open_exec(*name);471471- if (IS_ERR(file)) {472472- retval = PTR_ERR(file);473473- goto out;474474- }475475- retval = kernel_read(file, 0, bprm->buf, 128);476476- if (retval < 0)477477- goto dput_and_out;478478-479479- *interp_elf_ex = *(struct elfhdr *) bprm->buf;480480- }481481- *interpreter = file;482482- return 0;483483-484484-dput_and_out:485485- fput(file);486486-out:487487- kfree(*name);488488- return retval;489489-}490490-491491-static inline int verify_irix_interpreter(struct elfhdr *ihp)492492-{493493- if (memcmp(ihp->e_ident, ELFMAG, SELFMAG) != 0)494494- return -ELIBBAD;495495- return 0;496496-}497497-498498-#define EXEC_MAP_FLAGS (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE)499499-500500-static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnum,501501- unsigned int *estack, unsigned int *laddr,502502- unsigned int *scode, unsigned int *ebss,503503- unsigned int *ecode, unsigned int *edata,504504- unsigned int *ebrk)505505-{506506- unsigned int tmp;507507- int i, prot;508508-509509- for (i = 0; i < pnum; i++, epp++) {510510- if (epp->p_type != PT_LOAD)511511- continue;512512-513513- /* Map it. */514514- prot = (epp->p_flags & PF_R) ? PROT_READ : 0;515515- prot |= (epp->p_flags & PF_W) ? PROT_WRITE : 0;516516- prot |= (epp->p_flags & PF_X) ? PROT_EXEC : 0;517517- down_write(¤t->mm->mmap_sem);518518- (void) do_mmap(fp, (epp->p_vaddr & 0xfffff000),519519- (epp->p_filesz + (epp->p_vaddr & 0xfff)),520520- prot, EXEC_MAP_FLAGS,521521- (epp->p_offset & 0xfffff000));522522- up_write(¤t->mm->mmap_sem);523523-524524- /* Fixup location tracking vars. */525525- if ((epp->p_vaddr & 0xfffff000) < *estack)526526- *estack = (epp->p_vaddr & 0xfffff000);527527- if (!*laddr)528528- *laddr = epp->p_vaddr - epp->p_offset;529529- if (epp->p_vaddr < *scode)530530- *scode = epp->p_vaddr;531531-532532- tmp = epp->p_vaddr + epp->p_filesz;533533- if (tmp > *ebss)534534- *ebss = tmp;535535- if ((epp->p_flags & PF_X) && *ecode < tmp)536536- *ecode = tmp;537537- if (*edata < tmp)538538- *edata = tmp;539539-540540- tmp = epp->p_vaddr + epp->p_memsz;541541- if (tmp > *ebrk)542542- *ebrk = tmp;543543- }544544-545545-}546546-547547-static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,548548- struct file *interp, unsigned int *iladdr,549549- int pnum, mm_segment_t old_fs,550550- unsigned int *eentry)551551-{552552- int i;553553-554554- *eentry = 0xffffffff;555555- for (i = 0; i < pnum; i++, epp++) {556556- if (epp->p_type != PT_INTERP)557557- continue;558558-559559- /* We should have fielded this error elsewhere... */560560- if (*eentry != 0xffffffff)561561- return -1;562562-563563- set_fs(old_fs);564564- *eentry = load_irix_interp(ihp, interp, iladdr);565565- old_fs = get_fs();566566- set_fs(get_ds());567567-568568- fput(interp);569569-570570- if (*eentry == 0xffffffff)571571- return -1;572572- }573573- return 0;574574-}575575-576576-/*577577- * IRIX maps a page at 0x200000 that holds information about the578578- * process and the system, here we map the page and fill the579579- * structure580580- */581581-static int irix_map_prda_page(void)582582-{583583- unsigned long v;584584- struct prda *pp;585585-586586- down_write(¤t->mm->mmap_sem);587587- v = do_brk(PRDA_ADDRESS, PAGE_SIZE);588588- up_write(¤t->mm->mmap_sem);589589-590590- if (v != PRDA_ADDRESS)591591- return v; /* v must be an error code */592592-593593- pp = (struct prda *) v;594594- pp->prda_sys.t_pid = task_pid_vnr(current);595595- pp->prda_sys.t_prid = read_c0_prid();596596- pp->prda_sys.t_rpid = task_pid_vnr(current);597597-598598- /* We leave the rest set to zero */599599-600600- return 0;601601-}602602-603603-604604-605605-/* These are the functions used to load ELF style executables and shared606606- * libraries. There is no binary dependent code anywhere else.607607- */608608-static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)609609-{610610- struct elfhdr elf_ex, interp_elf_ex;611611- struct file *interpreter;612612- struct elf_phdr *elf_phdata, *elf_ihdr, *elf_ephdr;613613- unsigned int load_addr, elf_bss, elf_brk;614614- unsigned int elf_entry, interp_load_addr = 0;615615- unsigned int start_code, end_code, end_data, elf_stack;616616- int retval, has_interp, has_ephdr, size, i;617617- char *elf_interpreter;618618- mm_segment_t old_fs;619619-620620- load_addr = 0;621621- has_interp = has_ephdr = 0;622622- elf_ihdr = elf_ephdr = NULL;623623- elf_ex = *((struct elfhdr *) bprm->buf);624624- retval = -ENOEXEC;625625-626626- if (verify_binary(&elf_ex, bprm))627627- goto out;628628-629629- /*630630- * Telling -o32 static binaries from Linux and Irix apart from each631631- * other is difficult. There are 2 differences to be noted for static632632- * binaries from the 2 operating systems:633633- *634634- * 1) Irix binaries have their .text section before their .init635635- * section. Linux binaries are just the opposite.636636- *637637- * 2) Irix binaries usually have <= 12 sections and Linux638638- * binaries have > 20.639639- *640640- * We will use Method #2 since Method #1 would require us to read in641641- * the section headers which is way too much overhead. This appears642642- * to work for everything we have ran into so far. If anyone has a643643- * better method to tell the binaries apart, I'm listening.644644- */645645- if (elf_ex.e_shnum > 20)646646- goto out;647647-648648- print_elfhdr(&elf_ex);649649-650650- /* Now read in all of the header information */651651- size = elf_ex.e_phentsize * elf_ex.e_phnum;652652- if (size > 65536)653653- goto out;654654- elf_phdata = kmalloc(size, GFP_KERNEL);655655- if (elf_phdata == NULL) {656656- retval = -ENOMEM;657657- goto out;658658- }659659-660660- retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);661661- if (retval < 0)662662- goto out_free_ph;663663-664664- dump_phdrs(elf_phdata, elf_ex.e_phnum);665665-666666- /* Set some things for later. */667667- for (i = 0; i < elf_ex.e_phnum; i++) {668668- switch (elf_phdata[i].p_type) {669669- case PT_INTERP:670670- has_interp = 1;671671- elf_ihdr = &elf_phdata[i];672672- break;673673- case PT_PHDR:674674- has_ephdr = 1;675675- elf_ephdr = &elf_phdata[i];676676- break;677677- };678678- }679679-680680- pr_debug("\n");681681-682682- elf_bss = 0;683683- elf_brk = 0;684684-685685- elf_stack = 0xffffffff;686686- elf_interpreter = NULL;687687- start_code = 0xffffffff;688688- end_code = 0;689689- end_data = 0;690690-691691- /*692692- * If we get a return value, we change the value to be ENOEXEC693693- * so that we can exit gracefully and the main binary format694694- * search loop in 'fs/exec.c' will move onto the next handler695695- * which should be the normal ELF binary handler.696696- */697697- retval = look_for_irix_interpreter(&elf_interpreter, &interpreter,698698- &interp_elf_ex, elf_phdata, bprm,699699- elf_ex.e_phnum);700700- if (retval) {701701- retval = -ENOEXEC;702702- goto out_free_file;703703- }704704-705705- if (elf_interpreter) {706706- retval = verify_irix_interpreter(&interp_elf_ex);707707- if (retval)708708- goto out_free_interp;709709- }710710-711711- /* OK, we are done with that, now set up the arg stuff,712712- * and then start this sucker up.713713- */714714- retval = -E2BIG;715715- if (!bprm->sh_bang && !bprm->p)716716- goto out_free_interp;717717-718718- /* Flush all traces of the currently running executable */719719- retval = flush_old_exec(bprm);720720- if (retval)721721- goto out_free_dentry;722722-723723- /* OK, This is the point of no return */724724- current->mm->end_data = 0;725725- current->mm->end_code = 0;726726- current->mm->mmap = NULL;727727- current->flags &= ~PF_FORKNOEXEC;728728- elf_entry = (unsigned int) elf_ex.e_entry;729729-730730- /* Do this so that we can load the interpreter, if need be. We will731731- * change some of these later.732732- */733733- setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);734734- current->mm->start_stack = bprm->p;735735-736736- /* At this point, we assume that the image should be loaded at737737- * fixed address, not at a variable address.738738- */739739- old_fs = get_fs();740740- set_fs(get_ds());741741-742742- map_executable(bprm->file, elf_phdata, elf_ex.e_phnum, &elf_stack,743743- &load_addr, &start_code, &elf_bss, &end_code,744744- &end_data, &elf_brk);745745-746746- if (elf_interpreter) {747747- retval = map_interpreter(elf_phdata, &interp_elf_ex,748748- interpreter, &interp_load_addr,749749- elf_ex.e_phnum, old_fs, &elf_entry);750750- kfree(elf_interpreter);751751- if (retval) {752752- set_fs(old_fs);753753- printk("Unable to load IRIX ELF interpreter\n");754754- send_sig(SIGSEGV, current, 0);755755- retval = 0;756756- goto out_free_file;757757- }758758- }759759-760760- set_fs(old_fs);761761-762762- kfree(elf_phdata);763763- set_personality(PER_IRIX32);764764- set_binfmt(&irix_format);765765- compute_creds(bprm);766766- current->flags &= ~PF_FORKNOEXEC;767767- bprm->p = (unsigned long)768768- create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc,769769- (elf_interpreter ? &elf_ex : NULL),770770- load_addr, interp_load_addr, regs, elf_ephdr);771771- current->mm->start_brk = current->mm->brk = elf_brk;772772- current->mm->end_code = end_code;773773- current->mm->start_code = start_code;774774- current->mm->end_data = end_data;775775- current->mm->start_stack = bprm->p;776776-777777- /* Calling set_brk effectively mmaps the pages that we need for the778778- * bss and break sections.779779- */780780- set_brk(elf_bss, elf_brk);781781-782782- /*783783- * IRIX maps a page at 0x200000 which holds some system784784- * information. Programs depend on this.785785- */786786- if (irix_map_prda_page())787787- goto out_free_dentry;788788-789789- padzero(elf_bss);790790-791791- pr_debug("(start_brk) %lx\n" , (long) current->mm->start_brk);792792- pr_debug("(end_code) %lx\n" , (long) current->mm->end_code);793793- pr_debug("(start_code) %lx\n" , (long) current->mm->start_code);794794- pr_debug("(end_data) %lx\n" , (long) current->mm->end_data);795795- pr_debug("(start_stack) %lx\n" , (long) current->mm->start_stack);796796- pr_debug("(brk) %lx\n" , (long) current->mm->brk);797797-798798-#if 0 /* XXX No fucking way dude... */799799- /* Why this, you ask??? Well SVr4 maps page 0 as read-only,800800- * and some applications "depend" upon this behavior.801801- * Since we do not have the power to recompile these, we802802- * emulate the SVr4 behavior. Sigh.803803- */804804- down_write(¤t->mm->mmap_sem);805805- (void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,806806- MAP_FIXED | MAP_PRIVATE, 0);807807- up_write(¤t->mm->mmap_sem);808808-#endif809809-810810- start_thread(regs, elf_entry, bprm->p);811811- if (current->ptrace & PT_PTRACED)812812- send_sig(SIGTRAP, current, 0);813813- return 0;814814-out:815815- return retval;816816-817817-out_free_dentry:818818- allow_write_access(interpreter);819819- fput(interpreter);820820-out_free_interp:821821- kfree(elf_interpreter);822822-out_free_file:823823-out_free_ph:824824- kfree(elf_phdata);825825- goto out;826826-}827827-828828-/* This is really simpleminded and specialized - we are loading an829829- * a.out library that is given an ELF header.830830- */831831-static int load_irix_library(struct file *file)832832-{833833- struct elfhdr elf_ex;834834- struct elf_phdr *elf_phdata = NULL;835835- unsigned int len = 0;836836- int elf_bss = 0;837837- int retval;838838- unsigned int bss;839839- int error;840840- int i, j, k;841841-842842- error = kernel_read(file, 0, (char *) &elf_ex, sizeof(elf_ex));843843- if (error != sizeof(elf_ex))844844- return -ENOEXEC;845845-846846- if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)847847- return -ENOEXEC;848848-849849- /* First of all, some simple consistency checks. */850850- if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||851851- !file->f_op->mmap)852852- return -ENOEXEC;853853-854854- /* Now read in all of the header information. */855855- if (sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE)856856- return -ENOEXEC;857857-858858- elf_phdata = kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);859859- if (elf_phdata == NULL)860860- return -ENOMEM;861861-862862- retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata,863863- sizeof(struct elf_phdr) * elf_ex.e_phnum);864864-865865- j = 0;866866- for (i=0; i<elf_ex.e_phnum; i++)867867- if ((elf_phdata + i)->p_type == PT_LOAD) j++;868868-869869- if (j != 1) {870870- kfree(elf_phdata);871871- return -ENOEXEC;872872- }873873-874874- while (elf_phdata->p_type != PT_LOAD) elf_phdata++;875875-876876- /* Now use mmap to map the library into memory. */877877- down_write(¤t->mm->mmap_sem);878878- error = do_mmap(file,879879- elf_phdata->p_vaddr & 0xfffff000,880880- elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),881881- PROT_READ | PROT_WRITE | PROT_EXEC,882882- MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,883883- elf_phdata->p_offset & 0xfffff000);884884- up_write(¤t->mm->mmap_sem);885885-886886- k = elf_phdata->p_vaddr + elf_phdata->p_filesz;887887- if (k > elf_bss) elf_bss = k;888888-889889- if (error != (elf_phdata->p_vaddr & 0xfffff000)) {890890- kfree(elf_phdata);891891- return error;892892- }893893-894894- padzero(elf_bss);895895-896896- len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;897897- bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;898898- if (bss > len) {899899- down_write(¤t->mm->mmap_sem);900900- do_brk(len, bss-len);901901- up_write(¤t->mm->mmap_sem);902902- }903903- kfree(elf_phdata);904904- return 0;905905-}906906-907907-/* Called through irix_syssgi() to map an elf image given an FD,908908- * a phdr ptr USER_PHDRP in userspace, and a count CNT telling how many909909- * phdrs there are in the USER_PHDRP array. We return the vaddr the910910- * first phdr was successfully mapped to.911911- */912912-unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt)913913-{914914- unsigned long type, vaddr, filesz, offset, flags;915915- struct elf_phdr __user *hp;916916- struct file *filp;917917- int i, retval;918918-919919- pr_debug("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",920920- fd, user_phdrp, cnt);921921-922922- /* First get the verification out of the way. */923923- hp = user_phdrp;924924- if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) {925925- pr_debug("irix_mapelf: bad pointer to ELF PHDR!\n");926926-927927- return -EFAULT;928928- }929929-930930- dump_phdrs(user_phdrp, cnt);931931-932932- for (i = 0; i < cnt; i++, hp++) {933933- if (__get_user(type, &hp->p_type))934934- return -EFAULT;935935- if (type != PT_LOAD) {936936- printk("irix_mapelf: One section is not PT_LOAD!\n");937937- return -ENOEXEC;938938- }939939- }940940-941941- filp = fget(fd);942942- if (!filp)943943- return -EACCES;944944- if (!filp->f_op) {945945- printk("irix_mapelf: Bogon filp!\n");946946- fput(filp);947947- return -EACCES;948948- }949949-950950- hp = user_phdrp;951951- for (i = 0; i < cnt; i++, hp++) {952952- int prot;953953-954954- retval = __get_user(vaddr, &hp->p_vaddr);955955- retval |= __get_user(filesz, &hp->p_filesz);956956- retval |= __get_user(offset, &hp->p_offset);957957- retval |= __get_user(flags, &hp->p_flags);958958- if (retval)959959- return retval;960960-961961- prot = (flags & PF_R) ? PROT_READ : 0;962962- prot |= (flags & PF_W) ? PROT_WRITE : 0;963963- prot |= (flags & PF_X) ? PROT_EXEC : 0;964964-965965- down_write(¤t->mm->mmap_sem);966966- retval = do_mmap(filp, (vaddr & 0xfffff000),967967- (filesz + (vaddr & 0xfff)),968968- prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),969969- (offset & 0xfffff000));970970- up_write(¤t->mm->mmap_sem);971971-972972- if (retval != (vaddr & 0xfffff000)) {973973- printk("irix_mapelf: do_mmap fails with %d!\n", retval);974974- fput(filp);975975- return retval;976976- }977977- }978978-979979- pr_debug("irix_mapelf: Success, returning %08lx\n",980980- (unsigned long) user_phdrp->p_vaddr);981981-982982- fput(filp);983983-984984- if (__get_user(vaddr, &user_phdrp->p_vaddr))985985- return -EFAULT;986986-987987- return vaddr;988988-}989989-990990-/*991991- * ELF core dumper992992- *993993- * Modelled on fs/exec.c:aout_core_dump()994994- * Jeremy Fitzhardinge <jeremy@sw.oz.au>995995- */996996-997997-/* These are the only things you should do on a core-file: use only these998998- * functions to write out all the necessary info.999999- */10001000-static int dump_write(struct file *file, const void __user *addr, int nr)10011001-{10021002- return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;10031003-}10041004-10051005-static int dump_seek(struct file *file, off_t off)10061006-{10071007- if (file->f_op->llseek) {10081008- if (file->f_op->llseek(file, off, 0) != off)10091009- return 0;10101010- } else10111011- file->f_pos = off;10121012- return 1;10131013-}10141014-10151015-/* Decide whether a segment is worth dumping; default is yes to be10161016- * sure (missing info is worse than too much; etc).10171017- * Personally I'd include everything, and use the coredump limit...10181018- *10191019- * I think we should skip something. But I am not sure how. H.J.10201020- */10211021-static inline int maydump(struct vm_area_struct *vma)10221022-{10231023- if (!(vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)))10241024- return 0;10251025-#if 110261026- if (vma->vm_flags & (VM_WRITE|VM_GROWSUP|VM_GROWSDOWN))10271027- return 1;10281028- if (vma->vm_flags & (VM_READ|VM_EXEC|VM_EXECUTABLE|VM_SHARED))10291029- return 0;10301030-#endif10311031- return 1;10321032-}10331033-10341034-/* An ELF note in memory. */10351035-struct memelfnote10361036-{10371037- const char *name;10381038- int type;10391039- unsigned int datasz;10401040- void *data;10411041-};10421042-10431043-static int notesize(struct memelfnote *en)10441044-{10451045- int sz;10461046-10471047- sz = sizeof(struct elf_note);10481048- sz += roundup(strlen(en->name) + 1, 4);10491049- sz += roundup(en->datasz, 4);10501050-10511051- return sz;10521052-}10531053-10541054-#define DUMP_WRITE(addr, nr) \10551055- if (!dump_write(file, (addr), (nr))) \10561056- goto end_coredump;10571057-#define DUMP_SEEK(off) \10581058- if (!dump_seek(file, (off))) \10591059- goto end_coredump;10601060-10611061-static int writenote(struct memelfnote *men, struct file *file)10621062-{10631063- struct elf_note en;10641064-10651065- en.n_namesz = strlen(men->name) + 1;10661066- en.n_descsz = men->datasz;10671067- en.n_type = men->type;10681068-10691069- DUMP_WRITE(&en, sizeof(en));10701070- DUMP_WRITE(men->name, en.n_namesz);10711071- /* XXX - cast from long long to long to avoid need for libgcc.a */10721072- DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */10731073- DUMP_WRITE(men->data, men->datasz);10741074- DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */10751075-10761076- return 1;10771077-10781078-end_coredump:10791079- return 0;10801080-}10811081-#undef DUMP_WRITE10821082-#undef DUMP_SEEK10831083-10841084-#define DUMP_WRITE(addr, nr) \10851085- if (!dump_write(file, (addr), (nr))) \10861086- goto end_coredump;10871087-#define DUMP_SEEK(off) \10881088- if (!dump_seek(file, (off))) \10891089- goto end_coredump;10901090-10911091-/* Actual dumper.10921092- *10931093- * This is a two-pass process; first we find the offsets of the bits,10941094- * and then they are actually written out. If we run out of core limit10951095- * we just truncate.10961096- */10971097-static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)10981098-{10991099- int has_dumped = 0;11001100- mm_segment_t fs;11011101- int segs;11021102- int i;11031103- size_t size;11041104- struct vm_area_struct *vma;11051105- struct elfhdr elf;11061106- off_t offset = 0, dataoff;11071107- int numnote = 3;11081108- struct memelfnote notes[3];11091109- struct elf_prstatus prstatus; /* NT_PRSTATUS */11101110- elf_fpregset_t fpu; /* NT_PRFPREG */11111111- struct elf_prpsinfo psinfo; /* NT_PRPSINFO */11121112-11131113- /* Count what's needed to dump, up to the limit of coredump size. */11141114- segs = 0;11151115- size = 0;11161116- for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {11171117- if (maydump(vma))11181118- {11191119- int sz = vma->vm_end-vma->vm_start;11201120-11211121- if (size+sz >= limit)11221122- break;11231123- else11241124- size += sz;11251125- }11261126-11271127- segs++;11281128- }11291129- pr_debug("irix_core_dump: %d segs taking %d bytes\n", segs, size);11301130-11311131- /* Set up header. */11321132- memcpy(elf.e_ident, ELFMAG, SELFMAG);11331133- elf.e_ident[EI_CLASS] = ELFCLASS32;11341134- elf.e_ident[EI_DATA] = ELFDATA2LSB;11351135- elf.e_ident[EI_VERSION] = EV_CURRENT;11361136- elf.e_ident[EI_OSABI] = ELF_OSABI;11371137- memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);11381138-11391139- elf.e_type = ET_CORE;11401140- elf.e_machine = ELF_ARCH;11411141- elf.e_version = EV_CURRENT;11421142- elf.e_entry = 0;11431143- elf.e_phoff = sizeof(elf);11441144- elf.e_shoff = 0;11451145- elf.e_flags = 0;11461146- elf.e_ehsize = sizeof(elf);11471147- elf.e_phentsize = sizeof(struct elf_phdr);11481148- elf.e_phnum = segs+1; /* Include notes. */11491149- elf.e_shentsize = 0;11501150- elf.e_shnum = 0;11511151- elf.e_shstrndx = 0;11521152-11531153- fs = get_fs();11541154- set_fs(KERNEL_DS);11551155-11561156- has_dumped = 1;11571157- current->flags |= PF_DUMPCORE;11581158-11591159- DUMP_WRITE(&elf, sizeof(elf));11601160- offset += sizeof(elf); /* Elf header. */11611161- offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers. */11621162-11631163- /* Set up the notes in similar form to SVR4 core dumps made11641164- * with info from their /proc.11651165- */11661166- memset(&psinfo, 0, sizeof(psinfo));11671167- memset(&prstatus, 0, sizeof(prstatus));11681168-11691169- notes[0].name = "CORE";11701170- notes[0].type = NT_PRSTATUS;11711171- notes[0].datasz = sizeof(prstatus);11721172- notes[0].data = &prstatus;11731173- prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;11741174- prstatus.pr_sigpend = current->pending.signal.sig[0];11751175- prstatus.pr_sighold = current->blocked.sig[0];11761176- psinfo.pr_pid = prstatus.pr_pid = task_pid_vnr(current);11771177- psinfo.pr_ppid = prstatus.pr_ppid = task_pid_vnr(current->parent);11781178- psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_vnr(current);11791179- psinfo.pr_sid = prstatus.pr_sid = task_session_vnr(current);11801180- if (thread_group_leader(current)) {11811181- /*11821182- * This is the record for the group leader. Add in the11831183- * cumulative times of previous dead threads. This total11841184- * won't include the time of each live thread whose state11851185- * is included in the core dump. The final total reported11861186- * to our parent process when it calls wait4 will include11871187- * those sums as well as the little bit more time it takes11881188- * this and each other thread to finish dying after the11891189- * core dump synchronization phase.11901190- */11911191- jiffies_to_timeval(current->utime + current->signal->utime,11921192- &prstatus.pr_utime);11931193- jiffies_to_timeval(current->stime + current->signal->stime,11941194- &prstatus.pr_stime);11951195- } else {11961196- jiffies_to_timeval(current->utime, &prstatus.pr_utime);11971197- jiffies_to_timeval(current->stime, &prstatus.pr_stime);11981198- }11991199- jiffies_to_timeval(current->signal->cutime, &prstatus.pr_cutime);12001200- jiffies_to_timeval(current->signal->cstime, &prstatus.pr_cstime);12011201-12021202- if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) {12031203- printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) "12041204- "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs));12051205- } else {12061206- *(struct pt_regs *)&prstatus.pr_reg = *regs;12071207- }12081208-12091209- notes[1].name = "CORE";12101210- notes[1].type = NT_PRPSINFO;12111211- notes[1].datasz = sizeof(psinfo);12121212- notes[1].data = &psinfo;12131213- i = current->state ? ffz(~current->state) + 1 : 0;12141214- psinfo.pr_state = i;12151215- psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];12161216- psinfo.pr_zomb = psinfo.pr_sname == 'Z';12171217- psinfo.pr_nice = task_nice(current);12181218- psinfo.pr_flag = current->flags;12191219- psinfo.pr_uid = current->uid;12201220- psinfo.pr_gid = current->gid;12211221- {12221222- int i, len;12231223-12241224- set_fs(fs);12251225-12261226- len = current->mm->arg_end - current->mm->arg_start;12271227- len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;12281228- (void *) copy_from_user(&psinfo.pr_psargs,12291229- (const char __user *)current->mm->arg_start, len);12301230- for (i = 0; i < len; i++)12311231- if (psinfo.pr_psargs[i] == 0)12321232- psinfo.pr_psargs[i] = ' ';12331233- psinfo.pr_psargs[len] = 0;12341234-12351235- set_fs(KERNEL_DS);12361236- }12371237- strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));12381238-12391239- /* Try to dump the FPU. */12401240- prstatus.pr_fpvalid = dump_fpu(regs, &fpu);12411241- if (!prstatus.pr_fpvalid) {12421242- numnote--;12431243- } else {12441244- notes[2].name = "CORE";12451245- notes[2].type = NT_PRFPREG;12461246- notes[2].datasz = sizeof(fpu);12471247- notes[2].data = &fpu;12481248- }12491249-12501250- /* Write notes phdr entry. */12511251- {12521252- struct elf_phdr phdr;12531253- int sz = 0;12541254-12551255- for (i = 0; i < numnote; i++)12561256- sz += notesize(¬es[i]);12571257-12581258- phdr.p_type = PT_NOTE;12591259- phdr.p_offset = offset;12601260- phdr.p_vaddr = 0;12611261- phdr.p_paddr = 0;12621262- phdr.p_filesz = sz;12631263- phdr.p_memsz = 0;12641264- phdr.p_flags = 0;12651265- phdr.p_align = 0;12661266-12671267- offset += phdr.p_filesz;12681268- DUMP_WRITE(&phdr, sizeof(phdr));12691269- }12701270-12711271- /* Page-align dumped data. */12721272- dataoff = offset = roundup(offset, PAGE_SIZE);12731273-12741274- /* Write program headers for segments dump. */12751275- for (vma = current->mm->mmap, i = 0;12761276- i < segs && vma != NULL; vma = vma->vm_next) {12771277- struct elf_phdr phdr;12781278- size_t sz;12791279-12801280- i++;12811281-12821282- sz = vma->vm_end - vma->vm_start;12831283-12841284- phdr.p_type = PT_LOAD;12851285- phdr.p_offset = offset;12861286- phdr.p_vaddr = vma->vm_start;12871287- phdr.p_paddr = 0;12881288- phdr.p_filesz = maydump(vma) ? sz : 0;12891289- phdr.p_memsz = sz;12901290- offset += phdr.p_filesz;12911291- phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;12921292- if (vma->vm_flags & VM_WRITE)12931293- phdr.p_flags |= PF_W;12941294- if (vma->vm_flags & VM_EXEC)12951295- phdr.p_flags |= PF_X;12961296- phdr.p_align = PAGE_SIZE;12971297-12981298- DUMP_WRITE(&phdr, sizeof(phdr));12991299- }13001300-13011301- for (i = 0; i < numnote; i++)13021302- if (!writenote(¬es[i], file))13031303- goto end_coredump;13041304-13051305- set_fs(fs);13061306-13071307- DUMP_SEEK(dataoff);13081308-13091309- for (i = 0, vma = current->mm->mmap;13101310- i < segs && vma != NULL;13111311- vma = vma->vm_next) {13121312- unsigned long addr = vma->vm_start;13131313- unsigned long len = vma->vm_end - vma->vm_start;13141314-13151315- if (!maydump(vma))13161316- continue;13171317- i++;13181318- pr_debug("elf_core_dump: writing %08lx %lx\n", addr, len);13191319- DUMP_WRITE((void __user *)addr, len);13201320- }13211321-13221322- if ((off_t) file->f_pos != offset) {13231323- /* Sanity check. */13241324- printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",13251325- (off_t) file->f_pos, offset);13261326- }13271327-13281328-end_coredump:13291329- set_fs(fs);13301330- return has_dumped;13311331-}13321332-13331333-static int __init init_irix_binfmt(void)13341334-{13351335- extern int init_inventory(void);13361336- extern asmlinkage unsigned long sys_call_table;13371337- extern asmlinkage unsigned long sys_call_table_irix5;13381338-13391339- init_inventory();13401340-13411341- /*13421342- * Copy the IRIX5 syscall table (8000 bytes) into the main syscall13431343- * table. The IRIX5 calls are located by an offset of 8000 bytes13441344- * from the beginning of the main table.13451345- */13461346- memcpy((void *) ((unsigned long) &sys_call_table + 8000),13471347- &sys_call_table_irix5, 8000);13481348-13491349- return register_binfmt(&irix_format);13501350-}13511351-13521352-static void __exit exit_irix_binfmt(void)13531353-{13541354- /*13551355- * Remove the Irix ELF loader.13561356- */13571357- unregister_binfmt(&irix_format);13581358-}13591359-13601360-module_init(init_irix_binfmt)13611361-module_exit(exit_irix_binfmt)
-78
arch/mips/kernel/irixinv.c
···11-/*22- * Support the inventory interface for IRIX binaries33- * This is invoked before the mm layer is working, so we do not44- * use the linked lists for the inventory yet.55- *66- * Miguel de Icaza, 1997.77- */88-#include <linux/mm.h>99-#include <asm/inventory.h>1010-#include <asm/uaccess.h>1111-1212-#define MAX_INVENTORY 501313-int inventory_items = 0;1414-1515-static inventory_t inventory [MAX_INVENTORY];1616-1717-void add_to_inventory(int class, int type, int controller, int unit, int state)1818-{1919- inventory_t *ni = &inventory [inventory_items];2020-2121- if (inventory_items == MAX_INVENTORY)2222- return;2323-2424- ni->inv_class = class;2525- ni->inv_type = type;2626- ni->inv_controller = controller;2727- ni->inv_unit = unit;2828- ni->inv_state = state;2929- ni->inv_next = ni;3030- inventory_items++;3131-}3232-3333-int dump_inventory_to_user(void __user *userbuf, int size)3434-{3535- inventory_t *inv = &inventory [0];3636- inventory_t __user *user = userbuf;3737- int v;3838-3939- if (!access_ok(VERIFY_WRITE, userbuf, size))4040- return -EFAULT;4141-4242- for (v = 0; v < inventory_items; v++){4343- inv = &inventory [v];4444- if (copy_to_user (user, inv, sizeof (inventory_t)))4545- return -EFAULT;4646- user++;4747- }4848- return inventory_items * sizeof(inventory_t);4949-}5050-5151-int __init init_inventory(void)5252-{5353- /*5454- * gross hack while we put the right bits all over the kernel5555- * most likely this will not let just anyone run the X server5656- * until we put the right values all over the place5757- */5858- add_to_inventory(10, 3, 0, 0, 16400);5959- add_to_inventory(1, 1, 150, -1, 12);6060- add_to_inventory(1, 3, 0, 0, 8976);6161- add_to_inventory(1, 2, 0, 0, 8976);6262- add_to_inventory(4, 8, 0, 0, 2);6363- add_to_inventory(5, 5, 0, 0, 1);6464- add_to_inventory(3, 3, 0, 0, 32768);6565- add_to_inventory(3, 4, 0, 0, 32768);6666- add_to_inventory(3, 8, 0, 0, 524288);6767- add_to_inventory(3, 9, 0, 0, 64);6868- add_to_inventory(3, 1, 0, 0, 67108864);6969- add_to_inventory(12, 3, 0, 0, 16);7070- add_to_inventory(8, 7, 17, 0, 16777472);7171- add_to_inventory(8, 0, 0, 0, 1);7272- add_to_inventory(2, 1, 0, 13, 2);7373- add_to_inventory(2, 2, 0, 2, 0);7474- add_to_inventory(2, 2, 0, 1, 0);7575- add_to_inventory(7, 14, 0, 0, 6);7676-7777- return 0;7878-}
···11-/*22- * irixsig.c: WHEEE, IRIX signals! YOW, am I compatible or what?!?!33- *44- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)55- * Copyright (C) 1997 - 2000 Ralf Baechle (ralf@gnu.org)66- * Copyright (C) 2000 Silicon Graphics, Inc.77- */88-#include <linux/kernel.h>99-#include <linux/sched.h>1010-#include <linux/mm.h>1111-#include <linux/errno.h>1212-#include <linux/smp.h>1313-#include <linux/time.h>1414-#include <linux/ptrace.h>1515-#include <linux/resource.h>1616-1717-#include <asm/ptrace.h>1818-#include <asm/uaccess.h>1919-#include <asm/unistd.h>2020-2121-#undef DEBUG_SIG2222-2323-#define _S(nr) (1<<((nr)-1))2424-2525-#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))2626-2727-#define _IRIX_NSIG 1282828-#define _IRIX_NSIG_BPW BITS_PER_LONG2929-#define _IRIX_NSIG_WORDS (_IRIX_NSIG / _IRIX_NSIG_BPW)3030-3131-typedef struct {3232- unsigned long sig[_IRIX_NSIG_WORDS];3333-} irix_sigset_t;3434-3535-struct sigctx_irix5 {3636- u32 rmask, cp0_status;3737- u64 pc;3838- u64 regs[32];3939- u64 fpregs[32];4040- u32 usedfp, fpcsr, fpeir, sstk_flags;4141- u64 hi, lo;4242- u64 cp0_cause, cp0_badvaddr, _unused0;4343- irix_sigset_t sigset;4444- u64 weird_fpu_thing;4545- u64 _unused1[31];4646-};4747-4848-#ifdef DEBUG_SIG4949-/* Debugging */5050-static inline void dump_irix5_sigctx(struct sigctx_irix5 *c)5151-{5252- int i;5353-5454- printk("misc: rmask[%08lx] status[%08lx] pc[%08lx]\n",5555- (unsigned long) c->rmask,5656- (unsigned long) c->cp0_status,5757- (unsigned long) c->pc);5858- printk("regs: ");5959- for(i = 0; i < 16; i++)6060- printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]);6161- printk("\nregs: ");6262- for(i = 16; i < 32; i++)6363- printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]);6464- printk("\nfpregs: ");6565- for(i = 0; i < 16; i++)6666- printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]);6767- printk("\nfpregs: ");6868- for(i = 16; i < 32; i++)6969- printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]);7070- printk("misc: usedfp[%d] fpcsr[%08lx] fpeir[%08lx] stk_flgs[%08lx]\n",7171- (int) c->usedfp, (unsigned long) c->fpcsr,7272- (unsigned long) c->fpeir, (unsigned long) c->sstk_flags);7373- printk("misc: hi[%08lx] lo[%08lx] cause[%08lx] badvaddr[%08lx]\n",7474- (unsigned long) c->hi, (unsigned long) c->lo,7575- (unsigned long) c->cp0_cause, (unsigned long) c->cp0_badvaddr);7676- printk("misc: sigset<0>[%08lx] sigset<1>[%08lx] sigset<2>[%08lx] "7777- "sigset<3>[%08lx]\n", (unsigned long) c->sigset.sig[0],7878- (unsigned long) c->sigset.sig[1],7979- (unsigned long) c->sigset.sig[2],8080- (unsigned long) c->sigset.sig[3]);8181-}8282-#endif8383-8484-static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,8585- int signr, sigset_t *oldmask)8686-{8787- struct sigctx_irix5 __user *ctx;8888- unsigned long sp;8989- int error, i;9090-9191- sp = regs->regs[29];9292- sp -= sizeof(struct sigctx_irix5);9393- sp &= ~(0xf);9494- ctx = (struct sigctx_irix5 __user *) sp;9595- if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))9696- goto segv_and_exit;9797-9898- error = __put_user(0, &ctx->weird_fpu_thing);9999- error |= __put_user(~(0x00000001), &ctx->rmask);100100- error |= __put_user(0, &ctx->regs[0]);101101- for(i = 1; i < 32; i++)102102- error |= __put_user((u64) regs->regs[i], &ctx->regs[i]);103103-104104- error |= __put_user((u64) regs->hi, &ctx->hi);105105- error |= __put_user((u64) regs->lo, &ctx->lo);106106- error |= __put_user((u64) regs->cp0_epc, &ctx->pc);107107- error |= __put_user(!!used_math(), &ctx->usedfp);108108- error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);109109- error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);110110-111111- error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */112112-113113- error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0;114114-115115- if (error)116116- goto segv_and_exit;117117-118118-#ifdef DEBUG_SIG119119- dump_irix5_sigctx(ctx);120120-#endif121121-122122- regs->regs[4] = (unsigned long) signr;123123- regs->regs[5] = 0; /* XXX sigcode XXX */124124- regs->regs[6] = regs->regs[29] = sp;125125- regs->regs[7] = (unsigned long) ka->sa.sa_handler;126126- regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer;127127-128128- return 1;129129-130130-segv_and_exit:131131- force_sigsegv(signr, current);132132- return 0;133133-}134134-135135-static int inline136136-setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,137137- int signr, sigset_t *oldmask, siginfo_t *info)138138-{139139- printk("Aiee: setup_tr_frame wants to be written");140140- do_exit(SIGSEGV);141141-}142142-143143-static inline int handle_signal(unsigned long sig, siginfo_t *info,144144- struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)145145-{146146- int ret;147147-148148- switch(regs->regs[0]) {149149- case ERESTARTNOHAND:150150- regs->regs[2] = EINTR;151151- break;152152- case ERESTARTSYS:153153- if(!(ka->sa.sa_flags & SA_RESTART)) {154154- regs->regs[2] = EINTR;155155- break;156156- }157157- /* fallthrough */158158- case ERESTARTNOINTR: /* Userland will reload $v0. */159159- regs->cp0_epc -= 8;160160- }161161-162162- regs->regs[0] = 0; /* Don't deal with this again. */163163-164164- if (ka->sa.sa_flags & SA_SIGINFO)165165- ret = setup_irix_rt_frame(ka, regs, sig, oldset, info);166166- else167167- ret = setup_irix_frame(ka, regs, sig, oldset);168168-169169- spin_lock_irq(¤t->sighand->siglock);170170- sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask);171171- if (!(ka->sa.sa_flags & SA_NODEFER))172172- sigaddset(¤t->blocked, sig);173173- recalc_sigpending();174174- spin_unlock_irq(¤t->sighand->siglock);175175-176176- return ret;177177-}178178-179179-void do_irix_signal(struct pt_regs *regs)180180-{181181- struct k_sigaction ka;182182- siginfo_t info;183183- int signr;184184- sigset_t *oldset;185185-186186- /*187187- * We want the common case to go fast, which is why we may in certain188188- * cases get here from kernel mode. Just return without doing anything189189- * if so.190190- */191191- if (!user_mode(regs))192192- return;193193-194194- if (test_thread_flag(TIF_RESTORE_SIGMASK))195195- oldset = ¤t->saved_sigmask;196196- else197197- oldset = ¤t->blocked;198198-199199- signr = get_signal_to_deliver(&info, &ka, regs, NULL);200200- if (signr > 0) {201201- /* Whee! Actually deliver the signal. */202202- if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {203203- /* a signal was successfully delivered; the saved204204- * sigmask will have been stored in the signal frame,205205- * and will be restored by sigreturn, so we can simply206206- * clear the TIF_RESTORE_SIGMASK flag */207207- if (test_thread_flag(TIF_RESTORE_SIGMASK))208208- clear_thread_flag(TIF_RESTORE_SIGMASK);209209- }210210-211211- return;212212- }213213-214214- /*215215- * Who's code doesn't conform to the restartable syscall convention216216- * dies here!!! The li instruction, a single machine instruction,217217- * must directly be followed by the syscall instruction.218218- */219219- if (regs->regs[0]) {220220- if (regs->regs[2] == ERESTARTNOHAND ||221221- regs->regs[2] == ERESTARTSYS ||222222- regs->regs[2] == ERESTARTNOINTR) {223223- regs->cp0_epc -= 8;224224- }225225- if (regs->regs[2] == ERESTART_RESTARTBLOCK) {226226- regs->regs[2] = __NR_restart_syscall;227227- regs->regs[7] = regs->regs[26];228228- regs->cp0_epc -= 4;229229- }230230- regs->regs[0] = 0; /* Don't deal with this again. */231231- }232232-233233- /*234234- * If there's no signal to deliver, we just put the saved sigmask235235- * back236236- */237237- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {238238- clear_thread_flag(TIF_RESTORE_SIGMASK);239239- sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);240240- }241241-}242242-243243-asmlinkage void244244-irix_sigreturn(struct pt_regs *regs)245245-{246246- struct sigctx_irix5 __user *context, *magic;247247- unsigned long umask, mask;248248- u64 *fregs;249249- u32 usedfp;250250- int error, sig, i, base = 0;251251- sigset_t blocked;252252-253253- /* Always make any pending restarted system calls return -EINTR */254254- current_thread_info()->restart_block.fn = do_no_restart_syscall;255255-256256- if (regs->regs[2] == 1000)257257- base = 1;258258-259259- context = (struct sigctx_irix5 __user *) regs->regs[base + 4];260260- magic = (struct sigctx_irix5 __user *) regs->regs[base + 5];261261- sig = (int) regs->regs[base + 6];262262-#ifdef DEBUG_SIG263263- printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n",264264- current->comm, current->pid, context, magic, sig);265265-#endif266266- if (!context)267267- context = magic;268268- if (!access_ok(VERIFY_READ, context, sizeof(struct sigctx_irix5)))269269- goto badframe;270270-271271-#ifdef DEBUG_SIG272272- dump_irix5_sigctx(context);273273-#endif274274-275275- error = __get_user(regs->cp0_epc, &context->pc);276276- error |= __get_user(umask, &context->rmask);277277-278278- mask = 2;279279- for (i = 1; i < 32; i++, mask <<= 1) {280280- if (umask & mask)281281- error |= __get_user(regs->regs[i], &context->regs[i]);282282- }283283- error |= __get_user(regs->hi, &context->hi);284284- error |= __get_user(regs->lo, &context->lo);285285-286286- error |= __get_user(usedfp, &context->usedfp);287287- if ((umask & 1) && usedfp) {288288- fregs = (u64 *) ¤t->thread.fpu;289289-290290- for(i = 0; i < 32; i++)291291- error |= __get_user(fregs[i], &context->fpregs[i]);292292- error |= __get_user(current->thread.fpu.fcr31, &context->fpcsr);293293- }294294-295295- /* XXX do sigstack crapola here... XXX */296296-297297- error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0;298298-299299- if (error)300300- goto badframe;301301-302302- sigdelsetmask(&blocked, ~_BLOCKABLE);303303- spin_lock_irq(¤t->sighand->siglock);304304- current->blocked = blocked;305305- recalc_sigpending();306306- spin_unlock_irq(¤t->sighand->siglock);307307-308308- /*309309- * Don't let your children do this ...310310- */311311- __asm__ __volatile__(312312- "move\t$29,%0\n\t"313313- "j\tsyscall_exit"314314- :/* no outputs */315315- :"r" (®s));316316- /* Unreached */317317-318318-badframe:319319- force_sig(SIGSEGV, current);320320-}321321-322322-struct sigact_irix5 {323323- int flags;324324- void (*handler)(int);325325- u32 sigset[4];326326- int _unused0[2];327327-};328328-329329-#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility:330330- set only the low 32 bit of the sigset. */331331-332332-#ifdef DEBUG_SIG333333-static inline void dump_sigact_irix5(struct sigact_irix5 *p)334334-{335335- printk("<f[%d] hndlr[%08lx] msk[%08lx]>", p->flags,336336- (unsigned long) p->handler,337337- (unsigned long) p->sigset[0]);338338-}339339-#endif340340-341341-asmlinkage int342342-irix_sigaction(int sig, const struct sigaction __user *act,343343- struct sigaction __user *oact, void __user *trampoline)344344-{345345- struct k_sigaction new_ka, old_ka;346346- int ret;347347-348348-#ifdef DEBUG_SIG349349- printk(" (%d,%s,%s,%08lx) ", sig, (!new ? "0" : "NEW"),350350- (!old ? "0" : "OLD"), trampoline);351351- if(new) {352352- dump_sigact_irix5(new); printk(" ");353353- }354354-#endif355355- if (act) {356356- sigset_t mask;357357- int err;358358-359359- if (!access_ok(VERIFY_READ, act, sizeof(*act)))360360- return -EFAULT;361361- err = __get_user(new_ka.sa.sa_handler, &act->sa_handler);362362- err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);363363-364364- err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0;365365- if (err)366366- return err;367367-368368- /*369369- * Hmmm... methinks IRIX libc always passes a valid trampoline370370- * value for all invocations of sigaction. Will have to371371- * investigate. POSIX POSIX, die die die...372372- */373373- new_ka.sa_restorer = trampoline;374374- }375375-376376-/* XXX Implement SIG_SETMASK32 for IRIX compatibility */377377- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);378378-379379- if (!ret && oact) {380380- int err;381381-382382- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))383383- return -EFAULT;384384-385385- err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler);386386- err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);387387- err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask,388388- sizeof(sigset_t)) ? -EFAULT : 0;389389- if (err)390390- return -EFAULT;391391- }392392-393393- return ret;394394-}395395-396396-asmlinkage int irix_sigpending(irix_sigset_t __user *set)397397-{398398- return do_sigpending(set, sizeof(*set));399399-}400400-401401-asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,402402- irix_sigset_t __user *old)403403-{404404- sigset_t oldbits, newbits;405405-406406- if (new) {407407- if (!access_ok(VERIFY_READ, new, sizeof(*new)))408408- return -EFAULT;409409- if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4))410410- return -EFAULT;411411- sigdelsetmask(&newbits, ~_BLOCKABLE);412412-413413- spin_lock_irq(¤t->sighand->siglock);414414- oldbits = current->blocked;415415-416416- switch(how) {417417- case 1:418418- sigorsets(&newbits, &oldbits, &newbits);419419- break;420420-421421- case 2:422422- sigandsets(&newbits, &oldbits, &newbits);423423- break;424424-425425- case 3:426426- break;427427-428428- case 256:429429- siginitset(&newbits, newbits.sig[0]);430430- break;431431-432432- default:433433- spin_unlock_irq(¤t->sighand->siglock);434434- return -EINVAL;435435- }436436- recalc_sigpending();437437- spin_unlock_irq(¤t->sighand->siglock);438438- }439439- if (old)440440- return copy_to_user(old, ¤t->blocked,441441- sizeof(unsigned long)*4) ? -EFAULT : 0;442442-443443- return 0;444444-}445445-446446-asmlinkage int irix_sigsuspend(struct pt_regs *regs)447447-{448448- sigset_t newset;449449- sigset_t __user *uset;450450-451451- uset = (sigset_t __user *) regs->regs[4];452452- if (copy_from_user(&newset, uset, sizeof(sigset_t)))453453- return -EFAULT;454454- sigdelsetmask(&newset, ~_BLOCKABLE);455455-456456- spin_lock_irq(¤t->sighand->siglock);457457- current->saved_sigmask = current->blocked;458458- current->blocked = newset;459459- recalc_sigpending();460460- spin_unlock_irq(¤t->sighand->siglock);461461-462462- current->state = TASK_INTERRUPTIBLE;463463- schedule();464464- set_thread_flag(TIF_RESTORE_SIGMASK);465465- return -ERESTARTNOHAND;466466-}467467-468468-/* hate hate hate... */469469-struct irix5_siginfo {470470- int sig, code, error;471471- union {472472- char unused[128 - (3 * 4)]; /* Safety net. */473473- struct {474474- int pid;475475- union {476476- int uid;477477- struct {478478- int utime, status, stime;479479- } child;480480- } procdata;481481- } procinfo;482482-483483- unsigned long fault_addr;484484-485485- struct {486486- int fd;487487- long band;488488- } fileinfo;489489-490490- unsigned long sigval;491491- } stuff;492492-};493493-494494-asmlinkage int irix_sigpoll_sys(unsigned long __user *set,495495- struct irix5_siginfo __user *info, struct timespec __user *tp)496496-{497497- long expire = MAX_SCHEDULE_TIMEOUT;498498- sigset_t kset;499499- int i, sig, error, timeo = 0;500500- struct timespec ktp;501501-502502-#ifdef DEBUG_SIG503503- printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",504504- current->comm, current->pid, set, info, tp);505505-#endif506506-507507- /* Must always specify the signal set. */508508- if (!set)509509- return -EINVAL;510510-511511- if (copy_from_user(&kset, set, sizeof(set)))512512- return -EFAULT;513513-514514- if (info && clear_user(info, sizeof(*info))) {515515- error = -EFAULT;516516- goto out;517517- }518518-519519- if (tp) {520520- if (copy_from_user(&ktp, tp, sizeof(*tp)))521521- return -EFAULT;522522-523523- if (!ktp.tv_sec && !ktp.tv_nsec)524524- return -EINVAL;525525-526526- expire = timespec_to_jiffies(&ktp) +527527- (ktp.tv_sec || ktp.tv_nsec);528528- }529529-530530- while(1) {531531- long tmp = 0;532532-533533- expire = schedule_timeout_interruptible(expire);534534-535535- for (i=0; i < _IRIX_NSIG_WORDS; i++)536536- tmp |= (current->pending.signal.sig[i] & kset.sig[i]);537537-538538- if (tmp)539539- break;540540- if (!expire) {541541- timeo = 1;542542- break;543543- }544544- if (signal_pending(current))545545- return -EINTR;546546- }547547- if (timeo)548548- return -EAGAIN;549549-550550- for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {551551- if (sigismember (&kset, sig))552552- continue;553553- if (sigismember (¤t->pending.signal, sig)) {554554- /* XXX need more than this... */555555- if (info)556556- return copy_to_user(&info->sig, &sig, sizeof(sig));557557- return 0;558558- }559559- }560560-561561- /* Should not get here, but do something sane if we do. */562562- error = -EINTR;563563-564564-out:565565- return error;566566-}567567-568568-/* This is here because of irix5_siginfo definition. */569569-#define IRIX_P_PID 0570570-#define IRIX_P_PGID 2571571-#define IRIX_P_ALL 7572572-573573-#define W_EXITED 1574574-#define W_TRAPPED 2575575-#define W_STOPPED 4576576-#define W_CONT 8577577-#define W_NOHANG 64578578-579579-#define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)580580-581581-asmlinkage int irix_waitsys(int type, int upid,582582- struct irix5_siginfo __user *info, int options,583583- struct rusage __user *ru)584584-{585585- struct pid *pid = NULL;586586- int flag, retval;587587- DECLARE_WAITQUEUE(wait, current);588588- struct task_struct *tsk;589589- struct task_struct *p;590590- struct list_head *_p;591591-592592- if (!info)593593- return -EINVAL;594594-595595- if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))596596- return -EFAULT;597597-598598- if (ru)599599- if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)))600600- return -EFAULT;601601-602602- if (options & ~W_MASK)603603- return -EINVAL;604604-605605- if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL)606606- return -EINVAL;607607-608608- if (type != IRIX_P_ALL)609609- pid = find_get_pid(upid);610610- add_wait_queue(¤t->signal->wait_chldexit, &wait);611611-repeat:612612- flag = 0;613613- current->state = TASK_INTERRUPTIBLE;614614- read_lock(&tasklist_lock);615615- tsk = current;616616- list_for_each(_p, &tsk->children) {617617- p = list_entry(_p, struct task_struct, sibling);618618- if ((type == IRIX_P_PID) && task_pid(p) != pid)619619- continue;620620- if ((type == IRIX_P_PGID) && task_pgrp(p) != pid)621621- continue;622622- if ((p->exit_signal != SIGCHLD))623623- continue;624624- flag = 1;625625- switch (p->state) {626626- case TASK_STOPPED:627627- if (!p->exit_code)628628- continue;629629- if (!(options & (W_TRAPPED|W_STOPPED)) &&630630- !(p->ptrace & PT_PTRACED))631631- continue;632632- read_unlock(&tasklist_lock);633633-634634- /* move to end of parent's list to avoid starvation */635635- write_lock_irq(&tasklist_lock);636636- remove_parent(p);637637- add_parent(p);638638- write_unlock_irq(&tasklist_lock);639639- retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;640640- if (retval)641641- goto end_waitsys;642642-643643- retval = __put_user(SIGCHLD, &info->sig);644644- retval |= __put_user(0, &info->code);645645- retval |= __put_user(task_pid_vnr(p), &info->stuff.procinfo.pid);646646- retval |= __put_user((p->exit_code >> 8) & 0xff,647647- &info->stuff.procinfo.procdata.child.status);648648- retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);649649- retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);650650- if (retval)651651- goto end_waitsys;652652-653653- p->exit_code = 0;654654- goto end_waitsys;655655-656656- case EXIT_ZOMBIE:657657- current->signal->cutime += p->utime + p->signal->cutime;658658- current->signal->cstime += p->stime + p->signal->cstime;659659- if (ru != NULL)660660- getrusage(p, RUSAGE_BOTH, ru);661661- retval = __put_user(SIGCHLD, &info->sig);662662- retval |= __put_user(1, &info->code); /* CLD_EXITED */663663- retval |= __put_user(task_pid_vnr(p), &info->stuff.procinfo.pid);664664- retval |= __put_user((p->exit_code >> 8) & 0xff,665665- &info->stuff.procinfo.procdata.child.status);666666- retval |= __put_user(p->utime,667667- &info->stuff.procinfo.procdata.child.utime);668668- retval |= __put_user(p->stime,669669- &info->stuff.procinfo.procdata.child.stime);670670- if (retval)671671- goto end_waitsys;672672-673673- if (p->real_parent != p->parent) {674674- write_lock_irq(&tasklist_lock);675675- remove_parent(p);676676- p->parent = p->real_parent;677677- add_parent(p);678678- do_notify_parent(p, SIGCHLD);679679- write_unlock_irq(&tasklist_lock);680680- } else681681- release_task(p);682682- goto end_waitsys;683683- default:684684- continue;685685- }686686- tsk = next_thread(tsk);687687- }688688- read_unlock(&tasklist_lock);689689- if (flag) {690690- retval = 0;691691- if (options & W_NOHANG)692692- goto end_waitsys;693693- retval = -ERESTARTSYS;694694- if (signal_pending(current))695695- goto end_waitsys;696696- current->state = TASK_INTERRUPTIBLE;697697- schedule();698698- goto repeat;699699- }700700- retval = -ECHILD;701701-end_waitsys:702702- current->state = TASK_RUNNING;703703- remove_wait_queue(¤t->signal->wait_chldexit, &wait);704704- put_pid(pid);705705-706706- return retval;707707-}708708-709709-struct irix5_context {710710- u32 flags;711711- u32 link;712712- u32 sigmask[4];713713- struct { u32 sp, size, flags; } stack;714714- int regs[36];715715- u32 fpregs[32];716716- u32 fpcsr;717717- u32 _unused0;718718- u32 _unused1[47];719719- u32 weird_graphics_thing;720720-};721721-722722-asmlinkage int irix_getcontext(struct pt_regs *regs)723723-{724724- int error, i, base = 0;725725- struct irix5_context __user *ctx;726726- unsigned long flags;727727-728728- if (regs->regs[2] == 1000)729729- base = 1;730730- ctx = (struct irix5_context __user *) regs->regs[base + 4];731731-732732-#ifdef DEBUG_SIG733733- printk("[%s:%d] irix_getcontext(%p)\n",734734- current->comm, current->pid, ctx);735735-#endif736736-737737- if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))738738- return -EFAULT;739739-740740- error = __put_user(current->thread.irix_oldctx, &ctx->link);741741-742742- error |= __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0;743743-744744- /* XXX Do sigstack stuff someday... */745745- error |= __put_user(0, &ctx->stack.sp);746746- error |= __put_user(0, &ctx->stack.size);747747- error |= __put_user(0, &ctx->stack.flags);748748-749749- error |= __put_user(0, &ctx->weird_graphics_thing);750750- error |= __put_user(0, &ctx->regs[0]);751751- for (i = 1; i < 32; i++)752752- error |= __put_user(regs->regs[i], &ctx->regs[i]);753753- error |= __put_user(regs->lo, &ctx->regs[32]);754754- error |= __put_user(regs->hi, &ctx->regs[33]);755755- error |= __put_user(regs->cp0_cause, &ctx->regs[34]);756756- error |= __put_user(regs->cp0_epc, &ctx->regs[35]);757757-758758- flags = 0x0f;759759- if (!used_math()) {760760- flags &= ~(0x08);761761- } else {762762- /* XXX wheee... */763763- printk("Wheee, no code for saving IRIX FPU context yet.\n");764764- }765765- error |= __put_user(flags, &ctx->flags);766766-767767- return error;768768-}769769-770770-asmlinkage void irix_setcontext(struct pt_regs *regs)771771-{772772- struct irix5_context __user *ctx;773773- int err, base = 0;774774- u32 flags;775775-776776- if (regs->regs[2] == 1000)777777- base = 1;778778- ctx = (struct irix5_context __user *) regs->regs[base + 4];779779-780780-#ifdef DEBUG_SIG781781- printk("[%s:%d] irix_setcontext(%p)\n",782782- current->comm, current->pid, ctx);783783-#endif784784-785785- if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)))786786- goto segv_and_exit;787787-788788- err = __get_user(flags, &ctx->flags);789789- if (flags & 0x02) {790790- /* XXX sigstack garbage, todo... */791791- printk("Wheee, cannot do sigstack stuff in setcontext\n");792792- }793793-794794- if (flags & 0x04) {795795- int i;796796-797797- /* XXX extra control block stuff... todo... */798798- for (i = 1; i < 32; i++)799799- err |= __get_user(regs->regs[i], &ctx->regs[i]);800800- err |= __get_user(regs->lo, &ctx->regs[32]);801801- err |= __get_user(regs->hi, &ctx->regs[33]);802802- err |= __get_user(regs->cp0_epc, &ctx->regs[35]);803803- }804804-805805- if (flags & 0x08)806806- /* XXX fpu context, blah... */807807- printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n");808808-809809- err |= __get_user(current->thread.irix_oldctx, &ctx->link);810810- if (err)811811- goto segv_and_exit;812812-813813- /*814814- * Don't let your children do this ...815815- */816816- __asm__ __volatile__(817817- "move\t$29,%0\n\t"818818- "j\tsyscall_exit"819819- :/* no outputs */820820- :"r" (®s));821821- /* Unreached */822822-823823-segv_and_exit:824824- force_sigsegv(SIGSEGV, current);825825-}826826-827827-struct irix_sigstack {828828- unsigned long sp;829829- int status;830830-};831831-832832-asmlinkage int irix_sigstack(struct irix_sigstack __user *new,833833- struct irix_sigstack __user *old)834834-{835835-#ifdef DEBUG_SIG836836- printk("[%s:%d] irix_sigstack(%p,%p)\n",837837- current->comm, current->pid, new, old);838838-#endif839839- if (new) {840840- if (!access_ok(VERIFY_READ, new, sizeof(*new)))841841- return -EFAULT;842842- }843843-844844- if (old) {845845- if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))846846- return -EFAULT;847847- }848848-849849- return 0;850850-}851851-852852-struct irix_sigaltstack { unsigned long sp; int size; int status; };853853-854854-asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new,855855- struct irix_sigaltstack __user *old)856856-{857857-#ifdef DEBUG_SIG858858- printk("[%s:%d] irix_sigaltstack(%p,%p)\n",859859- current->comm, current->pid, new, old);860860-#endif861861- if (new)862862- if (!access_ok(VERIFY_READ, new, sizeof(*new)))863863- return -EFAULT;864864-865865- if (old) {866866- if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))867867- return -EFAULT;868868- }869869-870870- return 0;871871-}872872-873873-struct irix_procset {874874- int cmd, ltype, lid, rtype, rid;875875-};876876-877877-asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig)878878-{879879- if (!access_ok(VERIFY_READ, pset, sizeof(*pset)))880880- return -EFAULT;881881-#ifdef DEBUG_SIG882882- printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",883883- current->comm, current->pid,884884- pset->cmd, pset->ltype, pset->lid, pset->rtype, pset->rid,885885- sig);886886-#endif887887- return -EINVAL;888888-}
-7
arch/mips/kernel/process.c
···125125 *childregs = *regs;126126 childregs->regs[7] = 0; /* Clear error flag */127127128128-#if defined(CONFIG_BINFMT_IRIX)129129- if (current->personality != PER_LINUX) {130130- /* Under IRIX things are a little different. */131131- childregs->regs[3] = 1;132132- regs->regs[3] = 0;133133- }134134-#endif135128 childregs->regs[2] = 0; /* Child gets zero as return value */136129 regs->regs[2] = p->pid;137130
-19
arch/mips/kernel/scall32-o32.S
···34343535 lw t1, PT_EPC(sp) # skip syscall on return36363737-#if defined(CONFIG_BINFMT_IRIX)3838- sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number3939-#else4037 subu v0, v0, __NR_O32_Linux # check syscall number4138 sltiu t0, v0, __NR_O32_Linux_syscalls + 14242-#endif4339 addiu t1, 4 # skip to next instruction4440 sw t1, PT_EPC(sp)4541 beqz t0, illegal_syscall···260264 END(sys_sysmips)261265262266 LEAF(sys_syscall)263263-#if defined(CONFIG_BINFMT_IRIX)264264- sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number265265-#else266267 subu t0, a0, __NR_O32_Linux # check syscall number267268 sltiu v0, t0, __NR_O32_Linux_syscalls + 1268268-#endif269269 sll t1, t0, 3270270 beqz v0, einval271271272272 lw t2, sys_call_table(t1) # syscall routine273273274274-#if defined(CONFIG_BINFMT_IRIX)275275- li v1, 4000 # nr of sys_syscall276276-#else277274 li v1, 4000 - __NR_O32_Linux # index of sys_syscall278278-#endif279275 beq t0, v1, einval # do not recurse280276281277 /* Some syscalls like execve get their arguments from struct pt_regs···312324 .endm313325314326 .macro syscalltable315315-#if defined(CONFIG_BINFMT_IRIX)316316- mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */317317- mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */318318- mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */319319- mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */320320-#endif321321-322327 sys sys_syscall 8 /* 4000 */323328 sys sys_exit 1324329 sys sys_fork 0
-2140
arch/mips/kernel/sysirix.c
···11-/*22- * sysirix.c: IRIX system call emulation.33- *44- * Copyright (C) 1996 David S. Miller55- * Copyright (C) 1997 Miguel de Icaza66- * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle77- */88-#include <linux/kernel.h>99-#include <linux/sched.h>1010-#include <linux/binfmts.h>1111-#include <linux/capability.h>1212-#include <linux/highuid.h>1313-#include <linux/pagemap.h>1414-#include <linux/mm.h>1515-#include <linux/mman.h>1616-#include <linux/slab.h>1717-#include <linux/swap.h>1818-#include <linux/errno.h>1919-#include <linux/time.h>2020-#include <linux/timex.h>2121-#include <linux/times.h>2222-#include <linux/elf.h>2323-#include <linux/msg.h>2424-#include <linux/shm.h>2525-#include <linux/smp.h>2626-#include <linux/smp_lock.h>2727-#include <linux/utsname.h>2828-#include <linux/file.h>2929-#include <linux/vfs.h>3030-#include <linux/namei.h>3131-#include <linux/socket.h>3232-#include <linux/security.h>3333-#include <linux/syscalls.h>3434-#include <linux/resource.h>3535-3636-#include <asm/ptrace.h>3737-#include <asm/page.h>3838-#include <asm/uaccess.h>3939-#include <asm/inventory.h>4040-4141-/* 2,191 lines of complete and utter shit coming up... */4242-4343-extern int max_threads;4444-4545-/* The sysmp commands supported thus far. */4646-#define MP_NPROCS 1 /* # processor in complex */4747-#define MP_NAPROCS 2 /* # active processors in complex */4848-#define MP_PGSIZE 14 /* Return system page size in v1. */4949-5050-asmlinkage int irix_sysmp(struct pt_regs *regs)5151-{5252- unsigned long cmd;5353- int base = 0;5454- int error = 0;5555-5656- if(regs->regs[2] == 1000)5757- base = 1;5858- cmd = regs->regs[base + 4];5959- switch(cmd) {6060- case MP_PGSIZE:6161- error = PAGE_SIZE;6262- break;6363- case MP_NPROCS:6464- case MP_NAPROCS:6565- error = num_online_cpus();6666- break;6767- default:6868- printk("SYSMP[%s:%d]: Unsupported opcode %d\n",6969- current->comm, current->pid, (int)cmd);7070- error = -EINVAL;7171- break;7272- }7373-7474- return error;7575-}7676-7777-/* The prctl commands. */7878-#define PR_MAXPROCS 1 /* Tasks/user. */7979-#define PR_ISBLOCKED 2 /* If blocked, return 1. */8080-#define PR_SETSTACKSIZE 3 /* Set largest task stack size. */8181-#define PR_GETSTACKSIZE 4 /* Get largest task stack size. */8282-#define PR_MAXPPROCS 5 /* Num parallel tasks. */8383-#define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */8484-#define PR_SETEXITSIG 8 /* When task exit's, set signal. */8585-#define PR_RESIDENT 9 /* Make task unswappable. */8686-#define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */8787-#define PR_DETACHADDR 11 /* Disconnect a vma from a task. */8888-#define PR_TERMCHILD 12 /* Kill child if the parent dies. */8989-#define PR_GETSHMASK 13 /* Get the sproc() share mask. */9090-#define PR_GETNSHARE 14 /* Number of share group members. */9191-#define PR_COREPID 15 /* Add task pid to name when it core. */9292-#define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */9393-#define PR_PTHREADEXIT 17 /* Kill a pthread, only for IRIX 6.[234] */9494-9595-asmlinkage int irix_prctl(unsigned option, ...)9696-{9797- va_list args;9898- int error = 0;9999-100100- va_start(args, option);101101- switch (option) {102102- case PR_MAXPROCS:103103- printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",104104- current->comm, current->pid);105105- error = max_threads;106106- break;107107-108108- case PR_ISBLOCKED: {109109- struct task_struct *task;110110-111111- printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",112112- current->comm, current->pid);113113- read_lock(&tasklist_lock);114114- task = find_task_by_vpid(va_arg(args, pid_t));115115- error = -ESRCH;116116- if (error)117117- error = (task->run_list.next != NULL);118118- read_unlock(&tasklist_lock);119119- /* Can _your_ OS find this out that fast? */120120- break;121121- }122122-123123- case PR_SETSTACKSIZE: {124124- long value = va_arg(args, long);125125-126126- printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",127127- current->comm, current->pid, (unsigned long) value);128128- if (value > RLIM_INFINITY)129129- value = RLIM_INFINITY;130130- if (capable(CAP_SYS_ADMIN)) {131131- task_lock(current->group_leader);132132- current->signal->rlim[RLIMIT_STACK].rlim_max =133133- current->signal->rlim[RLIMIT_STACK].rlim_cur = value;134134- task_unlock(current->group_leader);135135- error = value;136136- break;137137- }138138- task_lock(current->group_leader);139139- if (value > current->signal->rlim[RLIMIT_STACK].rlim_max) {140140- error = -EINVAL;141141- task_unlock(current->group_leader);142142- break;143143- }144144- current->signal->rlim[RLIMIT_STACK].rlim_cur = value;145145- task_unlock(current->group_leader);146146- error = value;147147- break;148148- }149149-150150- case PR_GETSTACKSIZE:151151- printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n",152152- current->comm, current->pid);153153- error = current->signal->rlim[RLIMIT_STACK].rlim_cur;154154- break;155155-156156- case PR_MAXPPROCS:157157- printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",158158- current->comm, current->pid);159159- error = 1;160160- break;161161-162162- case PR_UNBLKONEXEC:163163- printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXEC\n",164164- current->comm, current->pid);165165- error = -EINVAL;166166- break;167167-168168- case PR_SETEXITSIG:169169- printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIG\n",170170- current->comm, current->pid);171171-172172- /* We can probably play some game where we set the task173173- * exit_code to some non-zero value when this is requested,174174- * and check whether exit_code is already set in do_exit().175175- */176176- error = -EINVAL;177177- break;178178-179179- case PR_RESIDENT:180180- printk("irix_prctl[%s:%d]: Wants PR_RESIDENT\n",181181- current->comm, current->pid);182182- error = 0; /* Compatibility indeed. */183183- break;184184-185185- case PR_ATTACHADDR:186186- printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDR\n",187187- current->comm, current->pid);188188- error = -EINVAL;189189- break;190190-191191- case PR_DETACHADDR:192192- printk("irix_prctl[%s:%d]: Wants PR_DETACHADDR\n",193193- current->comm, current->pid);194194- error = -EINVAL;195195- break;196196-197197- case PR_TERMCHILD:198198- printk("irix_prctl[%s:%d]: Wants PR_TERMCHILD\n",199199- current->comm, current->pid);200200- error = -EINVAL;201201- break;202202-203203- case PR_GETSHMASK:204204- printk("irix_prctl[%s:%d]: Wants PR_GETSHMASK\n",205205- current->comm, current->pid);206206- error = -EINVAL; /* Until I have the sproc() stuff in. */207207- break;208208-209209- case PR_GETNSHARE:210210- error = 0; /* Until I have the sproc() stuff in. */211211- break;212212-213213- case PR_COREPID:214214- printk("irix_prctl[%s:%d]: Wants PR_COREPID\n",215215- current->comm, current->pid);216216- error = -EINVAL;217217- break;218218-219219- case PR_ATTACHADDRPERM:220220- printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERM\n",221221- current->comm, current->pid);222222- error = -EINVAL;223223- break;224224-225225- default:226226- printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",227227- current->comm, current->pid, option);228228- error = -EINVAL;229229- break;230230- }231231- va_end(args);232232-233233- return error;234234-}235235-236236-#undef DEBUG_PROCGRPS237237-238238-extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt);239239-extern char *prom_getenv(char *name);240240-extern long prom_setenv(char *name, char *value);241241-242242-/* The syssgi commands supported thus far. */243243-#define SGI_SYSID 1 /* Return unique per-machine identifier. */244244-#define SGI_INVENT 5 /* Fetch inventory */245245-# define SGI_INV_SIZEOF 1246246-# define SGI_INV_READ 2247247-#define SGI_RDNAME 6 /* Return string name of a process. */248248-#define SGI_SETNVRAM 8 /* Set PROM variable. */249249-#define SGI_GETNVRAM 9 /* Get PROM variable. */250250-#define SGI_SETPGID 21 /* Set process group id. */251251-#define SGI_SYSCONF 22 /* POSIX sysconf garbage. */252252-#define SGI_PATHCONF 24 /* POSIX sysconf garbage. */253253-#define SGI_SETGROUPS 40 /* POSIX sysconf garbage. */254254-#define SGI_GETGROUPS 41 /* POSIX sysconf garbage. */255255-#define SGI_RUSAGE 56 /* BSD style rusage(). */256256-#define SGI_SSYNC 62 /* Synchronous fs sync. */257257-#define SGI_GETSID 65 /* SysVr4 get session id. */258258-#define SGI_ELFMAP 68 /* Map an elf image. */259259-#define SGI_TOSSTSAVE 108 /* Toss saved vma's. */260260-#define SGI_FP_BCOPY 129 /* Should FPU bcopy be used on this machine? */261261-#define SGI_PHYSP 1011 /* Translate virtual into physical page. */262262-263263-asmlinkage int irix_syssgi(struct pt_regs *regs)264264-{265265- unsigned long cmd;266266- int retval, base = 0;267267-268268- if (regs->regs[2] == 1000)269269- base = 1;270270-271271- cmd = regs->regs[base + 4];272272- switch(cmd) {273273- case SGI_SYSID: {274274- char __user *buf = (char __user *) regs->regs[base + 5];275275-276276- /* XXX Use ethernet addr.... */277277- retval = clear_user(buf, 64) ? -EFAULT : 0;278278- break;279279- }280280-#if 0281281- case SGI_RDNAME: {282282- int pid = (int) regs->regs[base + 5];283283- char __user *buf = (char __user *) regs->regs[base + 6];284284- struct task_struct *p;285285- char tcomm[sizeof(current->comm)];286286-287287- read_lock(&tasklist_lock);288288- p = find_task_by_pid(pid);289289- if (!p) {290290- read_unlock(&tasklist_lock);291291- retval = -ESRCH;292292- break;293293- }294294- get_task_comm(tcomm, p);295295- read_unlock(&tasklist_lock);296296-297297- /* XXX Need to check sizes. */298298- retval = copy_to_user(buf, tcomm, sizeof(tcomm)) ? -EFAULT : 0;299299- break;300300- }301301-302302- case SGI_GETNVRAM: {303303- char __user *name = (char __user *) regs->regs[base+5];304304- char __user *buf = (char __user *) regs->regs[base+6];305305- char *value;306306- return -EINVAL; /* til I fix it */307307- value = prom_getenv(name); /* PROM lock? */308308- if (!value) {309309- retval = -EINVAL;310310- break;311311- }312312- /* Do I strlen() for the length? */313313- retval = copy_to_user(buf, value, 128) ? -EFAULT : 0;314314- break;315315- }316316-317317- case SGI_SETNVRAM: {318318- char __user *name = (char __user *) regs->regs[base+5];319319- char __user *value = (char __user *) regs->regs[base+6];320320- return -EINVAL; /* til I fix it */321321- retval = prom_setenv(name, value);322322- /* XXX make sure retval conforms to syssgi(2) */323323- printk("[%s:%d] setnvram(\"%s\", \"%s\"): retval %d",324324- current->comm, current->pid, name, value, retval);325325-/* if (retval == PROM_ENOENT)326326- retval = -ENOENT; */327327- break;328328- }329329-#endif330330-331331- case SGI_SETPGID: {332332-#ifdef DEBUG_PROCGRPS333333- printk("[%s:%d] setpgid(%d, %d) ",334334- current->comm, current->pid,335335- (int) regs->regs[base + 5], (int)regs->regs[base + 6]);336336-#endif337337- retval = sys_setpgid(regs->regs[base + 5], regs->regs[base + 6]);338338-339339-#ifdef DEBUG_PROCGRPS340340- printk("retval=%d\n", retval);341341-#endif342342- }343343-344344- case SGI_SYSCONF: {345345- switch(regs->regs[base + 5]) {346346- case 1:347347- retval = (MAX_ARG_PAGES >> 4); /* XXX estimate... */348348- goto out;349349- case 2:350350- retval = max_threads;351351- goto out;352352- case 3:353353- retval = HZ;354354- goto out;355355- case 4:356356- retval = NGROUPS_MAX;357357- goto out;358358- case 5:359359- retval = sysctl_nr_open;360360- goto out;361361- case 6:362362- retval = 1;363363- goto out;364364- case 7:365365- retval = 1;366366- goto out;367367- case 8:368368- retval = 199009;369369- goto out;370370- case 11:371371- retval = PAGE_SIZE;372372- goto out;373373- case 12:374374- retval = 4;375375- goto out;376376- case 25:377377- case 26:378378- case 27:379379- case 28:380380- case 29:381381- case 30:382382- retval = 0;383383- goto out;384384- case 31:385385- retval = 32;386386- goto out;387387- default:388388- retval = -EINVAL;389389- goto out;390390- };391391- }392392-393393- case SGI_SETGROUPS:394394- retval = sys_setgroups((int) regs->regs[base + 5],395395- (gid_t __user *) regs->regs[base + 6]);396396- break;397397-398398- case SGI_GETGROUPS:399399- retval = sys_getgroups((int) regs->regs[base + 5],400400- (gid_t __user *) regs->regs[base + 6]);401401- break;402402-403403- case SGI_RUSAGE: {404404- struct rusage __user *ru = (struct rusage __user *) regs->regs[base + 6];405405-406406- switch((int) regs->regs[base + 5]) {407407- case 0:408408- /* rusage self */409409- retval = getrusage(current, RUSAGE_SELF, ru);410410- goto out;411411-412412- case -1:413413- /* rusage children */414414- retval = getrusage(current, RUSAGE_CHILDREN, ru);415415- goto out;416416-417417- default:418418- retval = -EINVAL;419419- goto out;420420- };421421- }422422-423423- case SGI_SSYNC:424424- sys_sync();425425- retval = 0;426426- break;427427-428428- case SGI_GETSID:429429-#ifdef DEBUG_PROCGRPS430430- printk("[%s:%d] getsid(%d) ", current->comm, current->pid,431431- (int) regs->regs[base + 5]);432432-#endif433433- retval = sys_getsid(regs->regs[base + 5]);434434-#ifdef DEBUG_PROCGRPS435435- printk("retval=%d\n", retval);436436-#endif437437- break;438438-439439- case SGI_ELFMAP:440440- retval = irix_mapelf((int) regs->regs[base + 5],441441- (struct elf_phdr __user *) regs->regs[base + 6],442442- (int) regs->regs[base + 7]);443443- break;444444-445445- case SGI_TOSSTSAVE:446446- /* XXX We don't need to do anything? */447447- retval = 0;448448- break;449449-450450- case SGI_FP_BCOPY:451451- retval = 0;452452- break;453453-454454- case SGI_PHYSP: {455455- unsigned long addr = regs->regs[base + 5];456456- int __user *pageno = (int __user *) (regs->regs[base + 6]);457457- struct mm_struct *mm = current->mm;458458- pgd_t *pgdp;459459- pud_t *pudp;460460- pmd_t *pmdp;461461- pte_t *ptep;462462-463463- down_read(&mm->mmap_sem);464464- pgdp = pgd_offset(mm, addr);465465- pudp = pud_offset(pgdp, addr);466466- pmdp = pmd_offset(pudp, addr);467467- ptep = pte_offset(pmdp, addr);468468- retval = -EINVAL;469469- if (ptep) {470470- pte_t pte = *ptep;471471-472472- if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {473473- /* b0rked on 64-bit */474474- retval = put_user((pte_val(pte) & PAGE_MASK) >>475475- PAGE_SHIFT, pageno);476476- }477477- }478478- up_read(&mm->mmap_sem);479479- break;480480- }481481-482482- case SGI_INVENT: {483483- int arg1 = (int) regs->regs [base + 5];484484- void __user *buffer = (void __user *) regs->regs [base + 6];485485- int count = (int) regs->regs [base + 7];486486-487487- switch (arg1) {488488- case SGI_INV_SIZEOF:489489- retval = sizeof(inventory_t);490490- break;491491- case SGI_INV_READ:492492- retval = dump_inventory_to_user(buffer, count);493493- break;494494- default:495495- retval = -EINVAL;496496- }497497- break;498498- }499499-500500- default:501501- printk("irix_syssgi: Unsupported command %d\n", (int)cmd);502502- retval = -EINVAL;503503- break;504504- };505505-506506-out:507507- return retval;508508-}509509-510510-asmlinkage int irix_gtime(struct pt_regs *regs)511511-{512512- return get_seconds();513513-}514514-515515-/*516516- * IRIX is completely broken... it returns 0 on success, otherwise517517- * ENOMEM.518518- */519519-asmlinkage int irix_brk(unsigned long brk)520520-{521521- unsigned long rlim;522522- unsigned long newbrk, oldbrk;523523- struct mm_struct *mm = current->mm;524524- int ret;525525-526526- down_write(&mm->mmap_sem);527527- if (brk < mm->end_code) {528528- ret = -ENOMEM;529529- goto out;530530- }531531-532532- newbrk = PAGE_ALIGN(brk);533533- oldbrk = PAGE_ALIGN(mm->brk);534534- if (oldbrk == newbrk) {535535- mm->brk = brk;536536- ret = 0;537537- goto out;538538- }539539-540540- /*541541- * Always allow shrinking brk542542- */543543- if (brk <= mm->brk) {544544- mm->brk = brk;545545- do_munmap(mm, newbrk, oldbrk-newbrk);546546- ret = 0;547547- goto out;548548- }549549- /*550550- * Check against rlimit and stack..551551- */552552- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;553553- if (rlim >= RLIM_INFINITY)554554- rlim = ~0;555555- if (brk - mm->end_code > rlim) {556556- ret = -ENOMEM;557557- goto out;558558- }559559-560560- /*561561- * Check against existing mmap mappings.562562- */563563- if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) {564564- ret = -ENOMEM;565565- goto out;566566- }567567-568568- /*569569- * Ok, looks good - let it rip.570570- */571571- if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) {572572- ret = -ENOMEM;573573- goto out;574574- }575575- mm->brk = brk;576576- ret = 0;577577-578578-out:579579- up_write(&mm->mmap_sem);580580- return ret;581581-}582582-583583-asmlinkage int irix_getpid(struct pt_regs *regs)584584-{585585- regs->regs[3] = task_pid_vnr(current->real_parent);586586- return task_pid_vnr(current);587587-}588588-589589-asmlinkage int irix_getuid(struct pt_regs *regs)590590-{591591- regs->regs[3] = current->euid;592592- return current->uid;593593-}594594-595595-asmlinkage int irix_getgid(struct pt_regs *regs)596596-{597597- regs->regs[3] = current->egid;598598- return current->gid;599599-}600600-601601-asmlinkage int irix_stime(int value)602602-{603603- int err;604604- struct timespec tv;605605-606606- tv.tv_sec = value;607607- tv.tv_nsec = 0;608608- err = security_settime(&tv, NULL);609609- if (err)610610- return err;611611-612612- write_seqlock_irq(&xtime_lock);613613- xtime.tv_sec = value;614614- xtime.tv_nsec = 0;615615- ntp_clear();616616- write_sequnlock_irq(&xtime_lock);617617-618618- return 0;619619-}620620-621621-static inline void jiffiestotv(unsigned long jiffies, struct timeval *value)622622-{623623- value->tv_usec = (jiffies % HZ) * (1000000 / HZ);624624- value->tv_sec = jiffies / HZ;625625-}626626-627627-static inline void getitimer_real(struct itimerval *value)628628-{629629- register unsigned long val, interval;630630-631631- interval = current->it_real_incr;632632- val = 0;633633- if (del_timer(¤t->real_timer)) {634634- unsigned long now = jiffies;635635- val = current->real_timer.expires;636636- add_timer(¤t->real_timer);637637- /* look out for negative/zero itimer.. */638638- if (val <= now)639639- val = now+1;640640- val -= now;641641- }642642- jiffiestotv(val, &value->it_value);643643- jiffiestotv(interval, &value->it_interval);644644-}645645-646646-asmlinkage unsigned int irix_alarm(unsigned int seconds)647647-{648648- return alarm_setitimer(seconds);649649-}650650-651651-asmlinkage int irix_pause(void)652652-{653653- current->state = TASK_INTERRUPTIBLE;654654- schedule();655655-656656- return -EINTR;657657-}658658-659659-/* XXX need more than this... */660660-asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name,661661- unsigned long flags, char __user *type, void __user *data, int datalen)662662-{663663- printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",664664- current->comm, current->pid,665665- dev_name, dir_name, flags, type, data, datalen);666666-667667- return sys_mount(dev_name, dir_name, type, flags, data);668668-}669669-670670-struct irix_statfs {671671- short f_type;672672- long f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree;673673- char f_fname[6], f_fpack[6];674674-};675675-676676-asmlinkage int irix_statfs(const char __user *path,677677- struct irix_statfs __user *buf, int len, int fs_type)678678-{679679- struct nameidata nd;680680- struct kstatfs kbuf;681681- int error, i;682682-683683- /* We don't support this feature yet. */684684- if (fs_type) {685685- error = -EINVAL;686686- goto out;687687- }688688- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) {689689- error = -EFAULT;690690- goto out;691691- }692692-693693- error = user_path_walk(path, &nd);694694- if (error)695695- goto out;696696-697697- error = vfs_statfs(nd.path.dentry, &kbuf);698698- if (error)699699- goto dput_and_out;700700-701701- error = __put_user(kbuf.f_type, &buf->f_type);702702- error |= __put_user(kbuf.f_bsize, &buf->f_bsize);703703- error |= __put_user(kbuf.f_frsize, &buf->f_frsize);704704- error |= __put_user(kbuf.f_blocks, &buf->f_blocks);705705- error |= __put_user(kbuf.f_bfree, &buf->f_bfree);706706- error |= __put_user(kbuf.f_files, &buf->f_files);707707- error |= __put_user(kbuf.f_ffree, &buf->f_ffree);708708- for (i = 0; i < 6; i++) {709709- error |= __put_user(0, &buf->f_fname[i]);710710- error |= __put_user(0, &buf->f_fpack[i]);711711- }712712-713713-dput_and_out:714714- path_put(&nd.path);715715-out:716716- return error;717717-}718718-719719-asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf)720720-{721721- struct kstatfs kbuf;722722- struct file *file;723723- int error, i;724724-725725- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) {726726- error = -EFAULT;727727- goto out;728728- }729729-730730- if (!(file = fget(fd))) {731731- error = -EBADF;732732- goto out;733733- }734734-735735- error = vfs_statfs(file->f_path.dentry, &kbuf);736736- if (error)737737- goto out_f;738738-739739- error = __put_user(kbuf.f_type, &buf->f_type);740740- error |= __put_user(kbuf.f_bsize, &buf->f_bsize);741741- error |= __put_user(kbuf.f_frsize, &buf->f_frsize);742742- error |= __put_user(kbuf.f_blocks, &buf->f_blocks);743743- error |= __put_user(kbuf.f_bfree, &buf->f_bfree);744744- error |= __put_user(kbuf.f_files, &buf->f_files);745745- error |= __put_user(kbuf.f_ffree, &buf->f_ffree);746746-747747- for (i = 0; i < 6; i++) {748748- error |= __put_user(0, &buf->f_fname[i]);749749- error |= __put_user(0, &buf->f_fpack[i]);750750- }751751-752752-out_f:753753- fput(file);754754-out:755755- return error;756756-}757757-758758-asmlinkage int irix_setpgrp(int flags)759759-{760760- int error;761761-762762-#ifdef DEBUG_PROCGRPS763763- printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);764764-#endif765765- if(!flags)766766- error = task_pgrp_vnr(current);767767- else768768- error = sys_setsid();769769-#ifdef DEBUG_PROCGRPS770770- printk("returning %d\n", error);771771-#endif772772-773773- return error;774774-}775775-776776-asmlinkage int irix_times(struct tms __user *tbuf)777777-{778778- int err = 0;779779-780780- if (tbuf) {781781- if (!access_ok(VERIFY_WRITE, tbuf, sizeof *tbuf))782782- return -EFAULT;783783-784784- err = __put_user(current->utime, &tbuf->tms_utime);785785- err |= __put_user(current->stime, &tbuf->tms_stime);786786- err |= __put_user(current->signal->cutime, &tbuf->tms_cutime);787787- err |= __put_user(current->signal->cstime, &tbuf->tms_cstime);788788- }789789-790790- return err;791791-}792792-793793-asmlinkage int irix_exec(struct pt_regs *regs)794794-{795795- int error, base = 0;796796- char *filename;797797-798798- if(regs->regs[2] == 1000)799799- base = 1;800800- filename = getname((char __user *) (long)regs->regs[base + 4]);801801- error = PTR_ERR(filename);802802- if (IS_ERR(filename))803803- return error;804804-805805- error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],806806- NULL, regs);807807- putname(filename);808808-809809- return error;810810-}811811-812812-asmlinkage int irix_exece(struct pt_regs *regs)813813-{814814- int error, base = 0;815815- char *filename;816816-817817- if (regs->regs[2] == 1000)818818- base = 1;819819- filename = getname((char __user *) (long)regs->regs[base + 4]);820820- error = PTR_ERR(filename);821821- if (IS_ERR(filename))822822- return error;823823- error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],824824- (char __user * __user *) (long)regs->regs[base + 6], regs);825825- putname(filename);826826-827827- return error;828828-}829829-830830-asmlinkage unsigned long irix_gethostid(void)831831-{832832- printk("[%s:%d]: irix_gethostid() called...\n",833833- current->comm, current->pid);834834-835835- return -EINVAL;836836-}837837-838838-asmlinkage unsigned long irix_sethostid(unsigned long val)839839-{840840- printk("[%s:%d]: irix_sethostid(%08lx) called...\n",841841- current->comm, current->pid, val);842842-843843- return -EINVAL;844844-}845845-846846-asmlinkage int irix_socket(int family, int type, int protocol)847847-{848848- switch(type) {849849- case 1:850850- type = SOCK_DGRAM;851851- break;852852-853853- case 2:854854- type = SOCK_STREAM;855855- break;856856-857857- case 3:858858- type = 9; /* Invalid... */859859- break;860860-861861- case 4:862862- type = SOCK_RAW;863863- break;864864-865865- case 5:866866- type = SOCK_RDM;867867- break;868868-869869- case 6:870870- type = SOCK_SEQPACKET;871871- break;872872-873873- default:874874- break;875875- }876876-877877- return sys_socket(family, type, protocol);878878-}879879-880880-asmlinkage int irix_getdomainname(char __user *name, int len)881881-{882882- int err;883883-884884- down_read(&uts_sem);885885- if (len > __NEW_UTS_LEN)886886- len = __NEW_UTS_LEN;887887- err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0;888888- up_read(&uts_sem);889889-890890- return err;891891-}892892-893893-asmlinkage unsigned long irix_getpagesize(void)894894-{895895- return PAGE_SIZE;896896-}897897-898898-asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,899899- unsigned long arg2, unsigned long arg3,900900- unsigned long arg4)901901-{902902- switch (opcode) {903903- case 0:904904- return sys_msgget((key_t) arg0, (int) arg1);905905- case 1:906906- return sys_msgctl((int) arg0, (int) arg1,907907- (struct msqid_ds __user *)arg2);908908- case 2:909909- return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1,910910- (size_t) arg2, (long) arg3, (int) arg4);911911- case 3:912912- return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1,913913- (size_t) arg2, (int) arg3);914914- default:915915- return -EINVAL;916916- }917917-}918918-919919-asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,920920- unsigned long arg2, unsigned long arg3)921921-{922922- switch (opcode) {923923- case 0:924924- return do_shmat((int) arg0, (char __user *) arg1, (int) arg2,925925- (unsigned long *) arg3);926926- case 1:927927- return sys_shmctl((int)arg0, (int)arg1,928928- (struct shmid_ds __user *)arg2);929929- case 2:930930- return sys_shmdt((char __user *)arg0);931931- case 3:932932- return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);933933- default:934934- return -EINVAL;935935- }936936-}937937-938938-asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,939939- unsigned long arg2, int arg3)940940-{941941- switch (opcode) {942942- case 0:943943- return sys_semctl((int) arg0, (int) arg1, (int) arg2,944944- (union semun) arg3);945945- case 1:946946- return sys_semget((key_t) arg0, (int) arg1, (int) arg2);947947- case 2:948948- return sys_semop((int) arg0, (struct sembuf __user *)arg1,949949- (unsigned int) arg2);950950- default:951951- return -EINVAL;952952- }953953-}954954-955955-static inline loff_t llseek(struct file *file, loff_t offset, int origin)956956-{957957- loff_t (*fn)(struct file *, loff_t, int);958958- loff_t retval;959959-960960- fn = default_llseek;961961- if (file->f_op && file->f_op->llseek)962962- fn = file->f_op->llseek;963963- lock_kernel();964964- retval = fn(file, offset, origin);965965- unlock_kernel();966966-967967- return retval;968968-}969969-970970-asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,971971- int origin)972972-{973973- struct file * file;974974- loff_t offset;975975- int retval;976976-977977- retval = -EBADF;978978- file = fget(fd);979979- if (!file)980980- goto bad;981981- retval = -EINVAL;982982- if (origin > 2)983983- goto out_putf;984984-985985- offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin);986986- retval = (int) offset;987987-988988-out_putf:989989- fput(file);990990-bad:991991- return retval;992992-}993993-994994-asmlinkage int irix_sginap(int ticks)995995-{996996- schedule_timeout_interruptible(ticks);997997- return 0;998998-}999999-10001000-asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len)10011001-{10021002- return -EINVAL;10031003-}10041004-10051005-asmlinkage int irix_gettimeofday(struct timeval __user *tv)10061006-{10071007- time_t sec;10081008- long nsec, seq;10091009- int err;10101010-10111011- if (!access_ok(VERIFY_WRITE, tv, sizeof(struct timeval)))10121012- return -EFAULT;10131013-10141014- do {10151015- seq = read_seqbegin(&xtime_lock);10161016- sec = xtime.tv_sec;10171017- nsec = xtime.tv_nsec;10181018- } while (read_seqretry(&xtime_lock, seq));10191019-10201020- err = __put_user(sec, &tv->tv_sec);10211021- err |= __put_user((nsec / 1000), &tv->tv_usec);10221022-10231023- return err;10241024-}10251025-10261026-#define IRIX_MAP_AUTOGROW 0x4010271027-10281028-asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,10291029- int flags, int fd, off_t offset)10301030-{10311031- struct file *file = NULL;10321032- unsigned long retval;10331033-10341034- if (!(flags & MAP_ANONYMOUS)) {10351035- if (!(file = fget(fd)))10361036- return -EBADF;10371037-10381038- /* Ok, bad taste hack follows, try to think in something else10391039- * when reading this. */10401040- if (flags & IRIX_MAP_AUTOGROW) {10411041- unsigned long old_pos;10421042- long max_size = offset + len;10431043-10441044- if (max_size > file->f_path.dentry->d_inode->i_size) {10451045- old_pos = sys_lseek(fd, max_size - 1, 0);10461046- sys_write(fd, (void __user *) "", 1);10471047- sys_lseek(fd, old_pos, 0);10481048- }10491049- }10501050- }10511051-10521052- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);10531053-10541054- down_write(¤t->mm->mmap_sem);10551055- retval = do_mmap(file, addr, len, prot, flags, offset);10561056- up_write(¤t->mm->mmap_sem);10571057- if (file)10581058- fput(file);10591059-10601060- return retval;10611061-}10621062-10631063-asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)10641064-{10651065- printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n",10661066- current->comm, current->pid, addr, len, behavior);10671067-10681068- return -EINVAL;10691069-}10701070-10711071-asmlinkage int irix_pagelock(char __user *addr, int len, int op)10721072-{10731073- printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",10741074- current->comm, current->pid, addr, len, op);10751075-10761076- return -EINVAL;10771077-}10781078-10791079-asmlinkage int irix_quotactl(struct pt_regs *regs)10801080-{10811081- printk("[%s:%d] Wheee.. irix_quotactl()\n",10821082- current->comm, current->pid);10831083-10841084- return -EINVAL;10851085-}10861086-10871087-asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)10881088-{10891089- int error;10901090-10911091-#ifdef DEBUG_PROCGRPS10921092- printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid,10931093- pid, pgrp);10941094-#endif10951095- if(!pid)10961096- pid = task_pid_vnr(current);10971097-10981098- /* Wheee, weird sysv thing... */10991099- if ((pgrp == 0) && (pid == task_pid_vnr(current)))11001100- error = sys_setsid();11011101- else11021102- error = sys_setpgid(pid, pgrp);11031103-11041104-#ifdef DEBUG_PROCGRPS11051105- printk("error = %d\n", error);11061106-#endif11071107-11081108- return error;11091109-}11101110-11111111-asmlinkage int irix_systeminfo(int cmd, char __user *buf, int cnt)11121112-{11131113- printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",11141114- current->comm, current->pid, cmd, buf, cnt);11151115-11161116- return -EINVAL;11171117-}11181118-11191119-struct iuname {11201120- char sysname[257], nodename[257], release[257];11211121- char version[257], machine[257];11221122- char m_type[257], base_rel[257];11231123- char _unused0[257], _unused1[257], _unused2[257];11241124- char _unused3[257], _unused4[257], _unused5[257];11251125-};11261126-11271127-asmlinkage int irix_uname(struct iuname __user *buf)11281128-{11291129- down_read(&uts_sem);11301130- if (copy_from_user(utsname()->sysname, buf->sysname, 65)11311131- || copy_from_user(utsname()->nodename, buf->nodename, 65)11321132- || copy_from_user(utsname()->release, buf->release, 65)11331133- || copy_from_user(utsname()->version, buf->version, 65)11341134- || copy_from_user(utsname()->machine, buf->machine, 65)) {11351135- return -EFAULT;11361136- }11371137- up_read(&uts_sem);11381138-11391139- return 1;11401140-}11411141-11421142-#undef DEBUG_XSTAT11431143-11441144-static int irix_xstat32_xlate(struct kstat *stat, void __user *ubuf)11451145-{11461146- struct xstat32 {11471147- u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;11481148- u32 st_rdev, st_pad2[2], st_size, st_pad3;11491149- u32 st_atime0, st_atime1;11501150- u32 st_mtime0, st_mtime1;11511151- u32 st_ctime0, st_ctime1;11521152- u32 st_blksize, st_blocks;11531153- char st_fstype[16];11541154- u32 st_pad4[8];11551155- } ub;11561156-11571157- if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))11581158- return -EOVERFLOW;11591159- ub.st_dev = sysv_encode_dev(stat->dev);11601160- ub.st_ino = stat->ino;11611161- ub.st_mode = stat->mode;11621162- ub.st_nlink = stat->nlink;11631163- SET_UID(ub.st_uid, stat->uid);11641164- SET_GID(ub.st_gid, stat->gid);11651165- ub.st_rdev = sysv_encode_dev(stat->rdev);11661166-#if BITS_PER_LONG == 3211671167- if (stat->size > MAX_NON_LFS)11681168- return -EOVERFLOW;11691169-#endif11701170- ub.st_size = stat->size;11711171- ub.st_atime0 = stat->atime.tv_sec;11721172- ub.st_atime1 = stat->atime.tv_nsec;11731173- ub.st_mtime0 = stat->mtime.tv_sec;11741174- ub.st_mtime1 = stat->atime.tv_nsec;11751175- ub.st_ctime0 = stat->ctime.tv_sec;11761176- ub.st_ctime1 = stat->atime.tv_nsec;11771177- ub.st_blksize = stat->blksize;11781178- ub.st_blocks = stat->blocks;11791179- strcpy(ub.st_fstype, "efs");11801180-11811181- return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;11821182-}11831183-11841184-static int irix_xstat64_xlate(struct kstat *stat, void __user *ubuf)11851185-{11861186- struct xstat64 {11871187- u32 st_dev; s32 st_pad1[3];11881188- unsigned long long st_ino;11891189- u32 st_mode;11901190- u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev;11911191- s32 st_pad2[2];11921192- long long st_size;11931193- s32 st_pad3;11941194- struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime;11951195- s32 st_blksize;11961196- long long st_blocks;11971197- char st_fstype[16];11981198- s32 st_pad4[8];11991199- } ks;12001200-12011201- if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))12021202- return -EOVERFLOW;12031203-12041204- ks.st_dev = sysv_encode_dev(stat->dev);12051205- ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;12061206- ks.st_ino = (unsigned long long) stat->ino;12071207- ks.st_mode = (u32) stat->mode;12081208- ks.st_nlink = (u32) stat->nlink;12091209- ks.st_uid = (s32) stat->uid;12101210- ks.st_gid = (s32) stat->gid;12111211- ks.st_rdev = sysv_encode_dev(stat->rdev);12121212- ks.st_pad2[0] = ks.st_pad2[1] = 0;12131213- ks.st_size = (long long) stat->size;12141214- ks.st_pad3 = 0;12151215-12161216- /* XXX hackety hack... */12171217- ks.st_atime.tv_sec = (s32) stat->atime.tv_sec;12181218- ks.st_atime.tv_nsec = stat->atime.tv_nsec;12191219- ks.st_mtime.tv_sec = (s32) stat->mtime.tv_sec;12201220- ks.st_mtime.tv_nsec = stat->mtime.tv_nsec;12211221- ks.st_ctime.tv_sec = (s32) stat->ctime.tv_sec;12221222- ks.st_ctime.tv_nsec = stat->ctime.tv_nsec;12231223-12241224- ks.st_blksize = (s32) stat->blksize;12251225- ks.st_blocks = (long long) stat->blocks;12261226- memset(ks.st_fstype, 0, 16);12271227- ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0;12281228- ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;12291229-12301230- /* Now write it all back. */12311231- return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0;12321232-}12331233-12341234-asmlinkage int irix_xstat(int version, char __user *filename, struct stat __user *statbuf)12351235-{12361236- int retval;12371237- struct kstat stat;12381238-12391239-#ifdef DEBUG_XSTAT12401240- printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",12411241- current->comm, current->pid, version, filename, statbuf);12421242-#endif12431243-12441244- retval = vfs_stat(filename, &stat);12451245- if (!retval) {12461246- switch(version) {12471247- case 2:12481248- retval = irix_xstat32_xlate(&stat, statbuf);12491249- break;12501250- case 3:12511251- retval = irix_xstat64_xlate(&stat, statbuf);12521252- break;12531253- default:12541254- retval = -EINVAL;12551255- }12561256- }12571257- return retval;12581258-}12591259-12601260-asmlinkage int irix_lxstat(int version, char __user *filename, struct stat __user *statbuf)12611261-{12621262- int error;12631263- struct kstat stat;12641264-12651265-#ifdef DEBUG_XSTAT12661266- printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",12671267- current->comm, current->pid, version, filename, statbuf);12681268-#endif12691269-12701270- error = vfs_lstat(filename, &stat);12711271-12721272- if (!error) {12731273- switch (version) {12741274- case 2:12751275- error = irix_xstat32_xlate(&stat, statbuf);12761276- break;12771277- case 3:12781278- error = irix_xstat64_xlate(&stat, statbuf);12791279- break;12801280- default:12811281- error = -EINVAL;12821282- }12831283- }12841284- return error;12851285-}12861286-12871287-asmlinkage int irix_fxstat(int version, int fd, struct stat __user *statbuf)12881288-{12891289- int error;12901290- struct kstat stat;12911291-12921292-#ifdef DEBUG_XSTAT12931293- printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",12941294- current->comm, current->pid, version, fd, statbuf);12951295-#endif12961296-12971297- error = vfs_fstat(fd, &stat);12981298- if (!error) {12991299- switch (version) {13001300- case 2:13011301- error = irix_xstat32_xlate(&stat, statbuf);13021302- break;13031303- case 3:13041304- error = irix_xstat64_xlate(&stat, statbuf);13051305- break;13061306- default:13071307- error = -EINVAL;13081308- }13091309- }13101310- return error;13111311-}13121312-13131313-asmlinkage int irix_xmknod(int ver, char __user *filename, int mode, unsigned dev)13141314-{13151315- int retval;13161316- printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",13171317- current->comm, current->pid, ver, filename, mode, dev);13181318-13191319- switch(ver) {13201320- case 2:13211321- /* shouldn't we convert here as well as on stat()? */13221322- retval = sys_mknod(filename, mode, dev);13231323- break;13241324-13251325- default:13261326- retval = -EINVAL;13271327- break;13281328- };13291329-13301330- return retval;13311331-}13321332-13331333-asmlinkage int irix_swapctl(int cmd, char __user *arg)13341334-{13351335- printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",13361336- current->comm, current->pid, cmd, arg);13371337-13381338- return -EINVAL;13391339-}13401340-13411341-struct irix_statvfs {13421342- u32 f_bsize; u32 f_frsize; u32 f_blocks;13431343- u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail;13441344- u32 f_fsid; char f_basetype[16];13451345- u32 f_flag; u32 f_namemax;13461346- char f_fstr[32]; u32 f_filler[16];13471347-};13481348-13491349-asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)13501350-{13511351- struct nameidata nd;13521352- struct kstatfs kbuf;13531353- int error, i;13541354-13551355- printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",13561356- current->comm, current->pid, fname, buf);13571357- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))13581358- return -EFAULT;13591359-13601360- error = user_path_walk(fname, &nd);13611361- if (error)13621362- goto out;13631363- error = vfs_statfs(nd.path.dentry, &kbuf);13641364- if (error)13651365- goto dput_and_out;13661366-13671367- error |= __put_user(kbuf.f_bsize, &buf->f_bsize);13681368- error |= __put_user(kbuf.f_frsize, &buf->f_frsize);13691369- error |= __put_user(kbuf.f_blocks, &buf->f_blocks);13701370- error |= __put_user(kbuf.f_bfree, &buf->f_bfree);13711371- error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */13721372- error |= __put_user(kbuf.f_files, &buf->f_files);13731373- error |= __put_user(kbuf.f_ffree, &buf->f_ffree);13741374- error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */13751375-#ifdef __MIPSEB__13761376- error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);13771377-#else13781378- error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);13791379-#endif13801380- for (i = 0; i < 16; i++)13811381- error |= __put_user(0, &buf->f_basetype[i]);13821382- error |= __put_user(0, &buf->f_flag);13831383- error |= __put_user(kbuf.f_namelen, &buf->f_namemax);13841384- for (i = 0; i < 32; i++)13851385- error |= __put_user(0, &buf->f_fstr[i]);13861386-13871387-dput_and_out:13881388- path_put(&nd.path);13891389-out:13901390- return error;13911391-}13921392-13931393-asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf)13941394-{13951395- struct kstatfs kbuf;13961396- struct file *file;13971397- int error, i;13981398-13991399- printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",14001400- current->comm, current->pid, fd, buf);14011401-14021402- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))14031403- return -EFAULT;14041404-14051405- if (!(file = fget(fd))) {14061406- error = -EBADF;14071407- goto out;14081408- }14091409- error = vfs_statfs(file->f_path.dentry, &kbuf);14101410- if (error)14111411- goto out_f;14121412-14131413- error = __put_user(kbuf.f_bsize, &buf->f_bsize);14141414- error |= __put_user(kbuf.f_frsize, &buf->f_frsize);14151415- error |= __put_user(kbuf.f_blocks, &buf->f_blocks);14161416- error |= __put_user(kbuf.f_bfree, &buf->f_bfree);14171417- error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */14181418- error |= __put_user(kbuf.f_files, &buf->f_files);14191419- error |= __put_user(kbuf.f_ffree, &buf->f_ffree);14201420- error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */14211421-#ifdef __MIPSEB__14221422- error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);14231423-#else14241424- error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);14251425-#endif14261426- for(i = 0; i < 16; i++)14271427- error |= __put_user(0, &buf->f_basetype[i]);14281428- error |= __put_user(0, &buf->f_flag);14291429- error |= __put_user(kbuf.f_namelen, &buf->f_namemax);14301430- error |= __clear_user(&buf->f_fstr, sizeof(buf->f_fstr)) ? -EFAULT : 0;14311431-14321432-out_f:14331433- fput(file);14341434-out:14351435- return error;14361436-}14371437-14381438-asmlinkage int irix_priocntl(struct pt_regs *regs)14391439-{14401440- printk("[%s:%d] Wheee.. irix_priocntl()\n",14411441- current->comm, current->pid);14421442-14431443- return -EINVAL;14441444-}14451445-14461446-asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)14471447-{14481448- printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n",14491449- current->comm, current->pid, pid, sig, code, val);14501450-14511451- return -EINVAL;14521452-}14531453-14541454-asmlinkage int irix_truncate64(char __user *name, int pad, int size1, int size2)14551455-{14561456- int retval;14571457-14581458- if (size1) {14591459- retval = -EINVAL;14601460- goto out;14611461- }14621462- retval = sys_truncate(name, size2);14631463-14641464-out:14651465- return retval;14661466-}14671467-14681468-asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2)14691469-{14701470- int retval;14711471-14721472- if (size1) {14731473- retval = -EINVAL;14741474- goto out;14751475- }14761476- retval = sys_ftruncate(fd, size2);14771477-14781478-out:14791479- return retval;14801480-}14811481-14821482-asmlinkage int irix_mmap64(struct pt_regs *regs)14831483-{14841484- int len, prot, flags, fd, off1, off2, error, base = 0;14851485- unsigned long addr, pgoff, *sp;14861486- struct file *file = NULL;14871487- int err;14881488-14891489- if (regs->regs[2] == 1000)14901490- base = 1;14911491- sp = (unsigned long *) (regs->regs[29] + 16);14921492- addr = regs->regs[base + 4];14931493- len = regs->regs[base + 5];14941494- prot = regs->regs[base + 6];14951495- if (!base) {14961496- flags = regs->regs[base + 7];14971497- if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long))))14981498- return -EFAULT;14991499- fd = sp[0];15001500- err = __get_user(off1, &sp[1]);15011501- err |= __get_user(off2, &sp[2]);15021502- } else {15031503- if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long))))15041504- return -EFAULT;15051505- err = __get_user(flags, &sp[0]);15061506- err |= __get_user(fd, &sp[1]);15071507- err |= __get_user(off1, &sp[2]);15081508- err |= __get_user(off2, &sp[3]);15091509- }15101510-15111511- if (err)15121512- return err;15131513-15141514- if (off1 & PAGE_MASK)15151515- return -EOVERFLOW;15161516-15171517- pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);15181518-15191519- if (!(flags & MAP_ANONYMOUS)) {15201520- if (!(file = fget(fd)))15211521- return -EBADF;15221522-15231523- /* Ok, bad taste hack follows, try to think in something else15241524- when reading this */15251525- if (flags & IRIX_MAP_AUTOGROW) {15261526- unsigned long old_pos;15271527- long max_size = off2 + len;15281528-15291529- if (max_size > file->f_path.dentry->d_inode->i_size) {15301530- old_pos = sys_lseek(fd, max_size - 1, 0);15311531- sys_write(fd, (void __user *) "", 1);15321532- sys_lseek(fd, old_pos, 0);15331533- }15341534- }15351535- }15361536-15371537- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);15381538-15391539- down_write(¤t->mm->mmap_sem);15401540- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);15411541- up_write(¤t->mm->mmap_sem);15421542-15431543- if (file)15441544- fput(file);15451545-15461546- return error;15471547-}15481548-15491549-asmlinkage int irix_dmi(struct pt_regs *regs)15501550-{15511551- printk("[%s:%d] Wheee.. irix_dmi()\n",15521552- current->comm, current->pid);15531553-15541554- return -EINVAL;15551555-}15561556-15571557-asmlinkage int irix_pread(int fd, char __user *buf, int cnt, int off64,15581558- int off1, int off2)15591559-{15601560- printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",15611561- current->comm, current->pid, fd, buf, cnt, off64, off1, off2);15621562-15631563- return -EINVAL;15641564-}15651565-15661566-asmlinkage int irix_pwrite(int fd, char __user *buf, int cnt, int off64,15671567- int off1, int off2)15681568-{15691569- printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",15701570- current->comm, current->pid, fd, buf, cnt, off64, off1, off2);15711571-15721572- return -EINVAL;15731573-}15741574-15751575-asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1,15761576- unsigned long arg2, unsigned long arg3,15771577- unsigned long arg4, unsigned long arg5)15781578-{15791579- printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"15801580- "%08lx,%08lx)\n",15811581- current->comm, current->pid, cmd, arg0, arg1, arg2,15821582- arg3, arg4, arg5);15831583-15841584- return -EINVAL;15851585-}15861586-15871587-struct irix_statvfs64 {15881588- u32 f_bsize; u32 f_frsize;15891589- u64 f_blocks; u64 f_bfree; u64 f_bavail;15901590- u64 f_files; u64 f_ffree; u64 f_favail;15911591- u32 f_fsid;15921592- char f_basetype[16];15931593- u32 f_flag; u32 f_namemax;15941594- char f_fstr[32];15951595- u32 f_filler[16];15961596-};15971597-15981598-asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *buf)15991599-{16001600- struct nameidata nd;16011601- struct kstatfs kbuf;16021602- int error, i;16031603-16041604- printk("[%s:%d] Wheee.. irix_statvfs64(%s,%p)\n",16051605- current->comm, current->pid, fname, buf);16061606- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64))) {16071607- error = -EFAULT;16081608- goto out;16091609- }16101610-16111611- error = user_path_walk(fname, &nd);16121612- if (error)16131613- goto out;16141614- error = vfs_statfs(nd.path.dentry, &kbuf);16151615- if (error)16161616- goto dput_and_out;16171617-16181618- error = __put_user(kbuf.f_bsize, &buf->f_bsize);16191619- error |= __put_user(kbuf.f_frsize, &buf->f_frsize);16201620- error |= __put_user(kbuf.f_blocks, &buf->f_blocks);16211621- error |= __put_user(kbuf.f_bfree, &buf->f_bfree);16221622- error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */16231623- error |= __put_user(kbuf.f_files, &buf->f_files);16241624- error |= __put_user(kbuf.f_ffree, &buf->f_ffree);16251625- error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */16261626-#ifdef __MIPSEB__16271627- error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);16281628-#else16291629- error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);16301630-#endif16311631- for(i = 0; i < 16; i++)16321632- error |= __put_user(0, &buf->f_basetype[i]);16331633- error |= __put_user(0, &buf->f_flag);16341634- error |= __put_user(kbuf.f_namelen, &buf->f_namemax);16351635- for(i = 0; i < 32; i++)16361636- error |= __put_user(0, &buf->f_fstr[i]);16371637-16381638-dput_and_out:16391639- path_put(&nd.path);16401640-out:16411641- return error;16421642-}16431643-16441644-asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf)16451645-{16461646- struct kstatfs kbuf;16471647- struct file *file;16481648- int error, i;16491649-16501650- printk("[%s:%d] Wheee.. irix_fstatvfs64(%d,%p)\n",16511651- current->comm, current->pid, fd, buf);16521652-16531653- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {16541654- error = -EFAULT;16551655- goto out;16561656- }16571657- if (!(file = fget(fd))) {16581658- error = -EBADF;16591659- goto out;16601660- }16611661- error = vfs_statfs(file->f_path.dentry, &kbuf);16621662- if (error)16631663- goto out_f;16641664-16651665- error = __put_user(kbuf.f_bsize, &buf->f_bsize);16661666- error |= __put_user(kbuf.f_frsize, &buf->f_frsize);16671667- error |= __put_user(kbuf.f_blocks, &buf->f_blocks);16681668- error |= __put_user(kbuf.f_bfree, &buf->f_bfree);16691669- error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */16701670- error |= __put_user(kbuf.f_files, &buf->f_files);16711671- error |= __put_user(kbuf.f_ffree, &buf->f_ffree);16721672- error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */16731673-#ifdef __MIPSEB__16741674- error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);16751675-#else16761676- error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);16771677-#endif16781678- for(i = 0; i < 16; i++)16791679- error |= __put_user(0, &buf->f_basetype[i]);16801680- error |= __put_user(0, &buf->f_flag);16811681- error |= __put_user(kbuf.f_namelen, &buf->f_namemax);16821682- error |= __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i])) ? -EFAULT : 0;16831683-16841684-out_f:16851685- fput(file);16861686-out:16871687- return error;16881688-}16891689-16901690-asmlinkage int irix_getmountid(char __user *fname, unsigned long __user *midbuf)16911691-{16921692- int err;16931693-16941694- printk("[%s:%d] irix_getmountid(%s, %p)\n",16951695- current->comm, current->pid, fname, midbuf);16961696- if (!access_ok(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4)))16971697- return -EFAULT;16981698-16991699- /*17001700- * The idea with this system call is that when trying to determine17011701- * 'pwd' and it's a toss-up for some reason, userland can use the17021702- * fsid of the filesystem to try and make the right decision, but17031703- * we don't have this so for now. XXX17041704- */17051705- err = __put_user(0, &midbuf[0]);17061706- err |= __put_user(0, &midbuf[1]);17071707- err |= __put_user(0, &midbuf[2]);17081708- err |= __put_user(0, &midbuf[3]);17091709-17101710- return err;17111711-}17121712-17131713-asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask,17141714- unsigned long arg, unsigned long sp, int slen)17151715-{17161716- printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n",17171717- current->comm, current->pid, entry, mask, arg, sp, slen);17181718-17191719- return -EINVAL;17201720-}17211721-17221722-#undef DEBUG_GETDENTS17231723-17241724-struct irix_dirent32 {17251725- u32 d_ino;17261726- u32 d_off;17271727- unsigned short d_reclen;17281728- char d_name[1];17291729-};17301730-17311731-struct irix_dirent32_callback {17321732- struct irix_dirent32 __user *current_dir;17331733- struct irix_dirent32 __user *previous;17341734- int count;17351735- int error;17361736-};17371737-17381738-#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))17391739-#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))17401740-17411741-static int irix_filldir32(void *__buf, const char *name,17421742- int namlen, loff_t offset, u64 ino, unsigned int d_type)17431743-{17441744- struct irix_dirent32 __user *dirent;17451745- struct irix_dirent32_callback *buf = __buf;17461746- unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);17471747- int err = 0;17481748- u32 d_ino;17491749-17501750-#ifdef DEBUG_GETDENTS17511751- printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",17521752- reclen, namlen, buf->count);17531753-#endif17541754- buf->error = -EINVAL; /* only used if we fail.. */17551755- if (reclen > buf->count)17561756- return -EINVAL;17571757- d_ino = ino;17581758- if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)17591759- return -EOVERFLOW;17601760- dirent = buf->previous;17611761- if (dirent)17621762- err = __put_user(offset, &dirent->d_off);17631763- dirent = buf->current_dir;17641764- err |= __put_user(dirent, &buf->previous);17651765- err |= __put_user(d_ino, &dirent->d_ino);17661766- err |= __put_user(reclen, &dirent->d_reclen);17671767- err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;17681768- err |= __put_user(0, &dirent->d_name[namlen]);17691769- dirent = (struct irix_dirent32 __user *) ((char __user *) dirent + reclen);17701770-17711771- buf->current_dir = dirent;17721772- buf->count -= reclen;17731773-17741774- return err;17751775-}17761776-17771777-asmlinkage int irix_ngetdents(unsigned int fd, void __user * dirent,17781778- unsigned int count, int __user *eob)17791779-{17801780- struct file *file;17811781- struct irix_dirent32 __user *lastdirent;17821782- struct irix_dirent32_callback buf;17831783- int error;17841784-17851785-#ifdef DEBUG_GETDENTS17861786- printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm,17871787- current->pid, fd, dirent, count, eob);17881788-#endif17891789- error = -EBADF;17901790- file = fget(fd);17911791- if (!file)17921792- goto out;17931793-17941794- buf.current_dir = (struct irix_dirent32 __user *) dirent;17951795- buf.previous = NULL;17961796- buf.count = count;17971797- buf.error = 0;17981798-17991799- error = vfs_readdir(file, irix_filldir32, &buf);18001800- if (error < 0)18011801- goto out_putf;18021802-18031803- error = buf.error;18041804- lastdirent = buf.previous;18051805- if (lastdirent) {18061806- put_user(file->f_pos, &lastdirent->d_off);18071807- error = count - buf.count;18081808- }18091809-18101810- if (put_user(0, eob) < 0) {18111811- error = -EFAULT;18121812- goto out_putf;18131813- }18141814-18151815-#ifdef DEBUG_GETDENTS18161816- printk("eob=%d returning %d\n", *eob, count - buf.count);18171817-#endif18181818- error = count - buf.count;18191819-18201820-out_putf:18211821- fput(file);18221822-out:18231823- return error;18241824-}18251825-18261826-struct irix_dirent64 {18271827- u64 d_ino;18281828- u64 d_off;18291829- unsigned short d_reclen;18301830- char d_name[1];18311831-};18321832-18331833-struct irix_dirent64_callback {18341834- struct irix_dirent64 __user *curr;18351835- struct irix_dirent64 __user *previous;18361836- int count;18371837- int error;18381838-};18391839-18401840-#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))18411841-#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))18421842-18431843-static int irix_filldir64(void *__buf, const char *name,18441844- int namlen, loff_t offset, u64 ino, unsigned int d_type)18451845-{18461846- struct irix_dirent64 __user *dirent;18471847- struct irix_dirent64_callback * buf = __buf;18481848- unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);18491849- int err = 0;18501850-18511851- if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))18521852- return -EFAULT;18531853-18541854- if (__put_user(-EINVAL, &buf->error)) /* only used if we fail.. */18551855- return -EFAULT;18561856- if (reclen > buf->count)18571857- return -EINVAL;18581858- dirent = buf->previous;18591859- if (dirent)18601860- err = __put_user(offset, &dirent->d_off);18611861- dirent = buf->curr;18621862- buf->previous = dirent;18631863- err |= __put_user(ino, &dirent->d_ino);18641864- err |= __put_user(reclen, &dirent->d_reclen);18651865- err |= __copy_to_user((char __user *)dirent->d_name, name, namlen)18661866- ? -EFAULT : 0;18671867- err |= __put_user(0, &dirent->d_name[namlen]);18681868-18691869- dirent = (struct irix_dirent64 __user *) ((char __user *) dirent + reclen);18701870-18711871- buf->curr = dirent;18721872- buf->count -= reclen;18731873-18741874- return err;18751875-}18761876-18771877-asmlinkage int irix_getdents64(int fd, void __user *dirent, int cnt)18781878-{18791879- struct file *file;18801880- struct irix_dirent64 __user *lastdirent;18811881- struct irix_dirent64_callback buf;18821882- int error;18831883-18841884-#ifdef DEBUG_GETDENTS18851885- printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm,18861886- current->pid, fd, dirent, cnt);18871887-#endif18881888- error = -EBADF;18891889- if (!(file = fget(fd)))18901890- goto out;18911891-18921892- error = -EFAULT;18931893- if (!access_ok(VERIFY_WRITE, dirent, cnt))18941894- goto out_f;18951895-18961896- error = -EINVAL;18971897- if (cnt < (sizeof(struct irix_dirent64) + 255))18981898- goto out_f;18991899-19001900- buf.curr = (struct irix_dirent64 __user *) dirent;19011901- buf.previous = NULL;19021902- buf.count = cnt;19031903- buf.error = 0;19041904- error = vfs_readdir(file, irix_filldir64, &buf);19051905- if (error < 0)19061906- goto out_f;19071907- lastdirent = buf.previous;19081908- if (!lastdirent) {19091909- error = buf.error;19101910- goto out_f;19111911- }19121912- if (put_user(file->f_pos, &lastdirent->d_off))19131913- return -EFAULT;19141914-#ifdef DEBUG_GETDENTS19151915- printk("returning %d\n", cnt - buf.count);19161916-#endif19171917- error = cnt - buf.count;19181918-19191919-out_f:19201920- fput(file);19211921-out:19221922- return error;19231923-}19241924-19251925-asmlinkage int irix_ngetdents64(int fd, void __user *dirent, int cnt, int *eob)19261926-{19271927- struct file *file;19281928- struct irix_dirent64 __user *lastdirent;19291929- struct irix_dirent64_callback buf;19301930- int error;19311931-19321932-#ifdef DEBUG_GETDENTS19331933- printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm,19341934- current->pid, fd, dirent, cnt);19351935-#endif19361936- error = -EBADF;19371937- if (!(file = fget(fd)))19381938- goto out;19391939-19401940- error = -EFAULT;19411941- if (!access_ok(VERIFY_WRITE, dirent, cnt) ||19421942- !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))19431943- goto out_f;19441944-19451945- error = -EINVAL;19461946- if (cnt < (sizeof(struct irix_dirent64) + 255))19471947- goto out_f;19481948-19491949- *eob = 0;19501950- buf.curr = (struct irix_dirent64 __user *) dirent;19511951- buf.previous = NULL;19521952- buf.count = cnt;19531953- buf.error = 0;19541954- error = vfs_readdir(file, irix_filldir64, &buf);19551955- if (error < 0)19561956- goto out_f;19571957- lastdirent = buf.previous;19581958- if (!lastdirent) {19591959- error = buf.error;19601960- goto out_f;19611961- }19621962- if (put_user(file->f_pos, &lastdirent->d_off))19631963- return -EFAULT;19641964-#ifdef DEBUG_GETDENTS19651965- printk("eob=%d returning %d\n", *eob, cnt - buf.count);19661966-#endif19671967- error = cnt - buf.count;19681968-19691969-out_f:19701970- fput(file);19711971-out:19721972- return error;19731973-}19741974-19751975-asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg)19761976-{19771977- int retval;19781978-19791979- switch (op) {19801980- case 1:19811981- /* Reboot */19821982- printk("[%s:%d] irix_uadmin: Wants to reboot...\n",19831983- current->comm, current->pid);19841984- retval = -EINVAL;19851985- goto out;19861986-19871987- case 2:19881988- /* Shutdown */19891989- printk("[%s:%d] irix_uadmin: Wants to shutdown...\n",19901990- current->comm, current->pid);19911991- retval = -EINVAL;19921992- goto out;19931993-19941994- case 4:19951995- /* Remount-root */19961996- printk("[%s:%d] irix_uadmin: Wants to remount root...\n",19971997- current->comm, current->pid);19981998- retval = -EINVAL;19991999- goto out;20002000-20012001- case 8:20022002- /* Kill all tasks. */20032003- printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n",20042004- current->comm, current->pid);20052005- retval = -EINVAL;20062006- goto out;20072007-20082008- case 256:20092009- /* Set magic mushrooms... */20102010- printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n",20112011- current->comm, current->pid, (int) func);20122012- retval = -EINVAL;20132013- goto out;20142014-20152015- default:20162016- printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n",20172017- current->comm, current->pid, (int) op);20182018- retval = -EINVAL;20192019- goto out;20202020- };20212021-20222022-out:20232023- return retval;20242024-}20252025-20262026-asmlinkage int irix_utssys(char __user *inbuf, int arg, int type, char __user *outbuf)20272027-{20282028- int retval;20292029-20302030- switch(type) {20312031- case 0:20322032- /* uname() */20332033- retval = irix_uname((struct iuname __user *)inbuf);20342034- goto out;20352035-20362036- case 2:20372037- /* ustat() */20382038- printk("[%s:%d] irix_utssys: Wants to do ustat()\n",20392039- current->comm, current->pid);20402040- retval = -EINVAL;20412041- goto out;20422042-20432043- case 3:20442044- /* fusers() */20452045- printk("[%s:%d] irix_utssys: Wants to do fusers()\n",20462046- current->comm, current->pid);20472047- retval = -EINVAL;20482048- goto out;20492049-20502050- default:20512051- printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n",20522052- current->comm, current->pid, (int) type);20532053- retval = -EINVAL;20542054- goto out;20552055- }20562056-20572057-out:20582058- return retval;20592059-}20602060-20612061-#undef DEBUG_FCNTL20622062-20632063-#define IRIX_F_ALLOCSP 1020642064-20652065-asmlinkage int irix_fcntl(int fd, int cmd, int arg)20662066-{20672067- int retval;20682068-20692069-#ifdef DEBUG_FCNTL20702070- printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm,20712071- current->pid, fd, cmd, arg);20722072-#endif20732073- if (cmd == IRIX_F_ALLOCSP){20742074- return 0;20752075- }20762076- retval = sys_fcntl(fd, cmd, arg);20772077-#ifdef DEBUG_FCNTL20782078- printk("%d\n", retval);20792079-#endif20802080- return retval;20812081-}20822082-20832083-asmlinkage int irix_ulimit(int cmd, int arg)20842084-{20852085- int retval;20862086-20872087- switch(cmd) {20882088- case 1:20892089- printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n",20902090- current->comm, current->pid);20912091- retval = -EINVAL;20922092- goto out;20932093-20942094- case 2:20952095- printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n",20962096- current->comm, current->pid);20972097- retval = -EINVAL;20982098- goto out;20992099-21002100- case 3:21012101- printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n",21022102- current->comm, current->pid);21032103- retval = -EINVAL;21042104- goto out;21052105-21062106- case 4:21072107-#if 021082108- printk("[%s:%d] irix_ulimit: Wants to get fd limit.\n",21092109- current->comm, current->pid);21102110- retval = -EINVAL;21112111- goto out;21122112-#endif21132113- retval = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;21142114- goto out;21152115-21162116- case 5:21172117- printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n",21182118- current->comm, current->pid);21192119- retval = -EINVAL;21202120- goto out;21212121-21222122- default:21232123- printk("[%s:%d] irix_ulimit: Unknown command [%d].\n",21242124- current->comm, current->pid, cmd);21252125- retval = -EINVAL;21262126- goto out;21272127- }21282128-out:21292129- return retval;21302130-}21312131-21322132-asmlinkage int irix_unimp(struct pt_regs *regs)21332133-{21342134- printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "21352135- "a3=%08lx\n", current->comm, current->pid,21362136- (int) regs->regs[2], (int) regs->regs[3],21372137- regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);21382138-21392139- return -ENOSYS;21402140-}
-24
include/asm-mips/inventory.h
···11-/*22- * Miguel de Icaza33- */44-#ifndef __ASM_INVENTORY_H55-#define __ASM_INVENTORY_H66-77-#include <linux/compiler.h>88-99-typedef struct inventory_s {1010- struct inventory_s *inv_next;1111- int inv_class;1212- int inv_type;1313- int inv_controller;1414- int inv_unit;1515- int inv_state;1616-} inventory_t;1717-1818-extern int inventory_items;1919-2020-extern void add_to_inventory(int class, int type, int controller, int unit, int state);2121-extern int dump_inventory_to_user(void __user *userbuf, int size);2222-extern int __init init_inventory(void);2323-2424-#endif /* __ASM_INVENTORY_H */
+5-20
include/asm-mips/namei.h
···11#ifndef _ASM_NAMEI_H22#define _ASM_NAMEI_H3344-#include <linux/personality.h>55-#include <linux/stddef.h>44+/*55+ * This dummy routine maybe changed to something useful66+ * for /usr/gnemul/ emulation stuff.77+ */6877-#define IRIX_EMUL "/usr/gnemul/irix/"88-#define RISCOS_EMUL "/usr/gnemul/riscos/"99-1010-static inline char *__emul_prefix(void)1111-{1212- switch (current->personality) {1313- case PER_IRIX32:1414- case PER_IRIXN32:1515- case PER_IRIX64:1616- return IRIX_EMUL;1717-1818- case PER_RISCOS:1919- return RISCOS_EMUL;2020-2121- default:2222- return NULL;2323- }2424-}99+#define __emul_prefix() NULL25102611#endif /* _ASM_NAMEI_H */
-41
include/asm-mips/prctl.h
···11-/*22- * IRIX prctl interface33- *44- * The IRIX kernel maps a page at PRDA_ADDRESS with the55- * contents of prda and fills it the bits on prda_sys.66- */77-88-#ifndef __PRCTL_H__99-#define __PRCTL_H__1010-1111-#define PRDA_ADDRESS 0x200000L1212-#define PRDA ((struct prda *) PRDA_ADDRESS)1313-1414-struct prda_sys {1515- pid_t t_pid;1616- u32 t_hint;1717- u32 t_dlactseq;1818- u32 t_fpflags;1919- u32 t_prid; /* processor type, $prid CP0 register */2020- u32 t_dlendseq;2121- u64 t_unused1[5];2222- pid_t t_rpid;2323- s32 t_resched;2424- u32 t_unused[8];2525- u32 t_cpu; /* current/last cpu */2626-2727- /* FIXME: The signal information, not supported by Linux now */2828- u32 t_flags; /* if true, then the sigprocmask is in userspace */2929- u32 t_sigprocmask [1]; /* the sigprocmask */3030-};3131-3232-struct prda {3333- char fill [0xe00];3434- struct prda_sys prda_sys;3535-};3636-3737-#define t_sys prda_sys3838-3939-ptrdiff_t prctl(int op, int v1, int v2);4040-4141-#endif