| diff -u --recursive --new-files pl12/linux/config.in linux/config.in |
| --- pl12/linux/config.in Sun Aug 15 11:24:56 1993 |
| +++ linux/config.in Sat Aug 21 10:51:27 1993 |
| @@ -13,6 +13,10 @@ |
| bool 'System V IPC' CONFIG_SYSVIPC y |
| bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y |
| * |
| +* Program binary formats |
| +* |
| +bool 'Elf executables' CONFIG_BINFMT_ELF y |
| +* |
| * SCSI support |
| * |
| bool 'SCSI support?' CONFIG_SCSI n |
| diff -u --recursive --new-files pl12/linux/fs/Makefile linux/fs/Makefile |
| --- pl12/linux/fs/Makefile Sun Mar 7 16:21:10 1993 |
| +++ linux/fs/Makefile Fri Aug 20 08:59:30 1993 |
| @@ -34,6 +34,9 @@ |
| FS_SUBDIRS := $(FS_SUBDIRS) xiafs |
| endif |
| |
| +ifdef CONFIG_BINFMT_ELF |
| +BINFMTS := $(BINFMTS) binfmt_elf.o |
| +endif |
| |
| .c.s: |
| $(CC) $(CFLAGS) -S $< |
| @@ -44,7 +47,7 @@ |
| |
| OBJS= open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \ |
| block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \ |
| - select.o fifo.o locks.o filesystems.o |
| + select.o fifo.o locks.o filesystems.o $(BINFMTS) |
| |
| all: fs.o filesystems.a |
| |
| diff -u --recursive --new-files pl12/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c |
| --- pl12/linux/fs/binfmt_elf.c |
| +++ linux/fs/binfmt_elf.c Fri Aug 20 08:59:30 1993 |
| @@ -0,0 +1,358 @@ |
| +#include <linux/fs.h> |
| +#include <linux/sched.h> |
| +#include <linux/mm.h> |
| +#include <linux/mman.h> |
| +#include <linux/a.out.h> |
| +#include <linux/errno.h> |
| +#include <linux/signal.h> |
| +#include <linux/binfmts.h> |
| +#include <asm/segment.h> |
| +#include <linux/string.h> |
| +#include <linux/fcntl.h> |
| +#include <linux/ptrace.h> |
| + |
| +extern "C" int sys_exit(int exit_code); |
| +extern "C" int sys_close(unsigned fd); |
| +extern "C" int sys_open(const char *, int, int); |
| + |
| +/* |
| + * These are the functions used to load ELF style executables and shared |
| + * libraries. There is no binary dependent code anywhere else. |
| + */ |
| + |
| +#include <linux/elf.h> |
| + |
| +int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) |
| +{ |
| + struct elfhdr elf_ex; |
| + struct file * file; |
| + struct exec ex; |
| + struct inode *interpreter_inode; |
| + int i; |
| + int old_fs; |
| + int error; |
| + struct elf_phdr * elf_ppnt, *elf_phdata; |
| + int elf_exec_fileno; |
| + unsigned int elf_bss, k, elf_brk; |
| + int retval; |
| + char * elf_interpreter; |
| + unsigned int elf_entry; |
| + int status; |
| + unsigned int start_code, end_code, end_data; |
| + unsigned int elf_stack; |
| + char passed_fileno[6]; |
| + |
| + status = 0; |
| + elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ |
| + |
| + if (elf_ex.e_ident[0] != 0x7f || |
| + strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) |
| + return -ENOEXEC; |
| + |
| + |
| + /* First of all, some simple consistency checks */ |
| + if(elf_ex.e_type != ET_EXEC || |
| + (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) || |
| + (!bprm->inode->i_op || !bprm->inode->i_op->bmap || |
| + !bprm->inode->i_op->default_file_ops->mmap)){ |
| + return -ENOEXEC; |
| + }; |
| + |
| + /* Now read in all of the header information */ |
| + |
| + elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize * |
| + elf_ex.e_phnum, GFP_KERNEL); |
| + |
| + old_fs = get_fs(); |
| + set_fs(get_ds()); |
| + retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata, |
| + elf_ex.e_phentsize * elf_ex.e_phnum); |
| + set_fs(old_fs); |
| + if (retval < 0) |
| + return retval; |
| + |
| + elf_ppnt = elf_phdata; |
| + |
| + elf_bss = 0; |
| + elf_brk = 0; |
| + |
| + elf_exec_fileno = open_inode(bprm->inode, O_RDONLY); |
| + |
| + if (elf_exec_fileno < 0) return elf_exec_fileno; |
| + |
| + file = current->filp[elf_exec_fileno]; |
| + |
| + elf_stack = 0xffffffff; |
| + elf_interpreter = NULL; |
| + start_code = 0; |
| + end_code = 0; |
| + end_data = 0; |
| + |
| + old_fs = get_fs(); |
| + set_fs(get_ds()); |
| + |
| + for(i=0;i < elf_ex.e_phnum; i++){ |
| + if(elf_ppnt->p_type == PT_INTERP) { |
| + /* This is the program interpreter used for shared libraries - |
| + for now assume that this is an a.out format binary */ |
| + |
| + elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, |
| + GFP_KERNEL); |
| + |
| + retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter, |
| + elf_ppnt->p_filesz); |
| + printk("Using ELF interpreter %s\n", elf_interpreter); |
| + if(retval >= 0) |
| + retval = namei(elf_interpreter, &interpreter_inode); |
| + if(retval >= 0) |
| + retval = read_exec(interpreter_inode,0,bprm->buf,128); |
| + |
| + if(retval >= 0){ |
| + ex = *((struct exec *) bprm->buf); /* exec-header */ |
| + |
| +#if 0 |
| + printk("Interpreter: %x %x %x\n",N_MAGIC(ex), ex.a_text,ex.a_data); |
| +#endif |
| + }; |
| + }; |
| + elf_ppnt++; |
| + }; |
| + |
| + set_fs(old_fs); |
| + |
| + /* Some simple consistency checks for the interpreter */ |
| + if(elf_interpreter){ |
| + if(retval < 0) { |
| + kfree(elf_interpreter); |
| + kfree(elf_phdata); |
| + return -ELIBACC; |
| + }; |
| + if((N_MAGIC(ex) != OMAGIC) && (N_MAGIC(ex) != ZMAGIC)) { |
| + kfree(elf_interpreter); |
| + kfree(elf_phdata); |
| + return -ELIBBAD; |
| + }; |
| + } |
| + |
| + /* OK, we are done with that, now set up the arg stuff, |
| + and then start this sucker up */ |
| + |
| + if (!bprm->sh_bang) { |
| + char * passed_p; |
| + |
| + sprintf(passed_fileno, "%d", elf_exec_fileno); |
| + passed_p = passed_fileno; |
| + |
| + if(elf_interpreter) { |
| + bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2); |
| + bprm->argc++; |
| + }; |
| + if (!bprm->p) { |
| + return -E2BIG; |
| + } |
| + } |
| + |
| + /* OK, This is the point of no return */ |
| + flush_old_exec(bprm); |
| + |
| + current->end_data = 0; |
| + current->end_code = 0; |
| + current->start_mmap = ELF_START_MMAP; |
| + current->mmap = NULL; |
| + elf_entry = (unsigned int) elf_ex.e_entry; |
| + |
| + /* Do this so that we can load the interpreter, if need be. We will |
| + change some of these later */ |
| + current->rss = 0; |
| + bprm->p += change_ldt(0, bprm->page); |
| + current->start_stack = bprm->p; |
| + |
| + /* Now we do a little grungy work by mmaping the ELF image into |
| + the correct location in memory. At this point, we assume that |
| + the image should be loaded at fixed address, not at a variable |
| + address. */ |
| + |
| + old_fs = get_fs(); |
| + set_fs(get_ds()); |
| + |
| + elf_ppnt = elf_phdata; |
| + for(i=0;i < elf_ex.e_phnum; i++){ |
| + |
| + if(elf_ppnt->p_type == PT_INTERP) { |
| + /* Set these up so that we are able to load the interpreter */ |
| + current->brk = ex.a_bss + |
| + (current->end_data = ex.a_data + |
| + (current->end_code = ex.a_text)); |
| + elf_entry = ex.a_entry; |
| + |
| + /* Now load the interpreter into user address space */ |
| + set_fs(old_fs); |
| + |
| + if (N_MAGIC(ex) == OMAGIC) { |
| + retval = read_exec(interpreter_inode, 32, (char *) 0, |
| + ex.a_text+ex.a_data); |
| + iput(interpreter_inode); |
| + } else if (N_MAGIC(ex) == ZMAGIC) { |
| + retval = read_exec(interpreter_inode, 1024, (char *) 0, |
| + ex.a_text+ex.a_data); |
| + iput(interpreter_inode); |
| + } else |
| + retval = -1; |
| + |
| + old_fs = get_fs(); |
| + set_fs(get_ds()); |
| + |
| + if(retval >= 0) |
| + zeromap_page_range((ex.a_text + ex.a_data + 0xfff) & |
| + 0xfffff000, ex.a_bss, PAGE_COPY); |
| + kfree(elf_interpreter); |
| + |
| + if(retval < 0) { |
| + kfree(elf_phdata); |
| + send_sig(SIGSEGV, current, 0); |
| + return 0; |
| + }; |
| + }; |
| + |
| + |
| + if(elf_ppnt->p_type == PT_LOAD) { |
| + error = do_mmap(file, |
| + elf_ppnt->p_vaddr & 0xfffff000, |
| + elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff), |
| + PROT_READ | PROT_WRITE | PROT_EXEC, |
| + MAP_FIXED | MAP_PRIVATE, |
| + elf_ppnt->p_offset & 0xfffff000); |
| + |
| +#ifdef LOW_ELF_STACK |
| + if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack) |
| + elf_stack = elf_ppnt->p_vaddr & 0xfffff000; |
| +#endif |
| + |
| + k = elf_ppnt->p_vaddr; |
| + if(k > start_code) start_code = k; |
| + k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; |
| + if(k > elf_bss) elf_bss = k; |
| + if((elf_ppnt->p_flags | PROT_WRITE) && end_code < k) |
| + end_code = k; |
| + if(end_data < k) end_data = k; |
| + k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz; |
| + if(k > elf_brk) elf_brk = k; |
| + |
| + if(status == 0xffffffff) { |
| + set_fs(old_fs); |
| + kfree(elf_phdata); |
| + send_sig(SIGSEGV, current, 0); |
| + return 0; |
| + }; |
| + }; |
| + elf_ppnt++; |
| + }; |
| + set_fs(old_fs); |
| + |
| + kfree(elf_phdata); |
| + |
| + if(!elf_interpreter) sys_close(elf_exec_fileno); |
| + current->elf_executable = 1; |
| + current->executable = bprm->inode; |
| + bprm->inode->i_count++; |
| +#ifdef LOW_ELF_STACK |
| + current->start_stack = p = elf_stack - 4; |
| +#endif |
| + bprm->p -= MAX_ARG_PAGES*PAGE_SIZE; |
| + bprm->p = (unsigned long) create_tables((char *)bprm->p,bprm->argc,bprm->envc); |
| + if(elf_interpreter) current->arg_start += strlen(passed_fileno) + 1; |
| + current->start_brk = current->brk = elf_brk; |
| + current->end_code = end_code; |
| + current->start_code = start_code; |
| + current->start_stack = bprm->p; |
| + current->suid = current->euid = bprm->e_uid; |
| + current->sgid = current->egid = bprm->e_gid; |
| + zeromap_page_range((elf_bss + 0xfff) & 0xfffff000, elf_brk - elf_bss, |
| + PAGE_COPY); |
| + regs->eip = elf_entry; /* eip, magic happens :-) */ |
| + regs->esp = bprm->p; /* stack pointer */ |
| + if (current->flags & PF_PTRACED) |
| + send_sig(SIGTRAP, current, 0); |
| + |
| + return 0; |
| +} |
| + |
| + |
| +int load_elf_library(int fd){ |
| + struct file * file; |
| + struct elfhdr elf_ex; |
| + struct elf_phdr *elf_phdata = NULL; |
| + struct inode * inode; |
| + unsigned int len; |
| + int old_fs, retval; |
| + unsigned int bss; |
| + int error; |
| + int i,j; |
| + |
| + len = 0; |
| + file = current->filp[fd]; |
| + inode = file->f_inode; |
| + |
| + set_fs(KERNEL_DS); |
| + if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) { |
| + sys_close(fd); |
| + return -EACCES; |
| + } |
| + set_fs(USER_DS); |
| + |
| + if (elf_ex.e_ident[0] != 0x7f || |
| + strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) |
| + return -ENOEXEC; |
| + |
| + /* First of all, some simple consistency checks */ |
| + if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || |
| + (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) || |
| + (!inode->i_op || !inode->i_op->bmap || |
| + !inode->i_op->default_file_ops->mmap)){ |
| + return -ENOEXEC; |
| + }; |
| + |
| + /* Now read in all of the header information */ |
| + |
| + if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) |
| + return -ENOEXEC; |
| + |
| + elf_phdata = (struct elf_phdr *) |
| + kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL); |
| + |
| + old_fs = get_fs(); |
| + set_fs(get_ds()); |
| + retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata, |
| + sizeof(struct elf_phdr) * elf_ex.e_phnum); |
| + set_fs(old_fs); |
| + |
| + j = 0; |
| + for(i=0; i<elf_ex.e_phnum; i++) |
| + if((elf_phdata + i)->p_type == PT_LOAD) j++; |
| + |
| + if(j != 1) { |
| + kfree(elf_phdata); |
| + return -ENOEXEC; |
| + }; |
| + |
| + while(elf_phdata->p_type != PT_LOAD) elf_phdata++; |
| + |
| + /* Now use mmap to map the library into memory. */ |
| + error = do_mmap(file, |
| + elf_phdata->p_vaddr & 0xfffff000, |
| + elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff), |
| + PROT_READ | PROT_WRITE | PROT_EXEC, |
| + MAP_FIXED | MAP_PRIVATE, |
| + elf_phdata->p_offset & 0xfffff000); |
| + |
| + sys_close(fd); |
| + if (error != elf_phdata->p_vaddr & 0xfffff000) |
| + return error; |
| + len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000; |
| + bss = elf_phdata->p_memsz + elf_phdata->p_vaddr; |
| + if (bss > len) |
| + zeromap_page_range(len, bss-len, PAGE_COPY); |
| + kfree(elf_phdata); |
| + return 0; |
| +} |
| + |
| diff -u --recursive --new-files pl12/linux/fs/exec.c linux/fs/exec.c |
| --- pl12/linux/fs/exec.c Sun Aug 15 11:33:07 1993 |
| +++ linux/fs/exec.c Fri Aug 20 08:59:31 1993 |
| @@ -50,7 +50,7 @@ |
| |
| extern void shm_exit (void); |
| |
| -static int open_inode(struct inode * inode, int mode) |
| +int open_inode(struct inode * inode, int mode) |
| { |
| int error, fd; |
| struct file *f, **fpp; |
| @@ -316,7 +316,7 @@ |
| * it is expensive to load a segment register, we try to avoid calling |
| * set_fs() unless we absolutely have to. |
| */ |
| -static unsigned long copy_strings(int argc,char ** argv,unsigned long *page, |
| +unsigned long copy_strings(int argc,char ** argv,unsigned long *page, |
| unsigned long p, int from_kmem) |
| { |
| char *tmp, *pag = NULL; |
| @@ -649,6 +649,7 @@ |
| } |
| } |
| |
| + bprm.sh_bang = sh_bang; |
| fmt = formats; |
| do { |
| int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary; |
| @@ -694,9 +695,16 @@ |
| struct pt_regs * regs); |
| extern int load_aout_library(int fd); |
| |
| +extern int load_elf_binary(struct linux_binprm *, |
| + struct pt_regs * regs); |
| +extern int load_elf_library(int fd); |
| + |
| /* Here are the actual binaries that will be accepted */ |
| struct linux_binfmt formats[] = { |
| {load_aout_binary, load_aout_library}, |
| +#ifdef CONFIG_BINFMT_ELF |
| + {load_elf_binary, load_elf_library}, |
| +#endif |
| {NULL, NULL} |
| }; |
| |
| @@ -713,17 +721,20 @@ |
| unsigned long p = bprm->p; |
| |
| ex = *((struct exec *) bprm->buf); /* exec-header */ |
| - if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) || |
| + if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && |
| + N_MAGIC(ex) != QMAGIC) || |
| ex.a_trsize || ex.a_drsize || |
| bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) { |
| return -ENOEXEC; |
| } |
| - if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) && |
| + |
| + if (N_MAGIC(ex) == ZMAGIC && |
| (N_TXTOFF(ex) < bprm->inode->i_sb->s_blocksize)) { |
| printk("N_TXTOFF < BLOCK_SIZE. Please convert binary."); |
| return -ENOEXEC; |
| } |
| - if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) != OMAGIC) { |
| + |
| + if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) == ZMAGIC) { |
| printk("N_TXTOFF != BLOCK_SIZE. See a.out.h."); |
| return -ENOEXEC; |
| } |
| @@ -732,7 +743,10 @@ |
| flush_old_exec(bprm); |
| current->start_brk = current->brk = ex.a_bss + |
| (current->end_data = ex.a_data + |
| - (current->end_code = ex.a_text)); |
| + (current->end_code = N_TXTADDR(ex) + ex.a_text)); |
| + |
| + current->start_code += N_TXTADDR(ex); |
| + |
| current->rss = 0; |
| current->suid = current->euid = bprm->e_uid; |
| current->mmap = NULL; |
| @@ -751,23 +765,25 @@ |
| file = current->filp[fd]; |
| if (!file->f_op || !file->f_op->mmap) { |
| sys_close(fd); |
| - read_exec(bprm->inode, 1024, (char *) 0, ex.a_text+ex.a_data); |
| + read_exec(bprm->inode, N_TXTOFF(ex), |
| + (char *) N_TXTADDR(ex), ex.a_text+ex.a_data); |
| goto beyond_if; |
| } |
| - error = do_mmap(file, 0, ex.a_text, |
| + error = do_mmap(file, N_TXTADDR(ex), ex.a_text, |
| PROT_READ | PROT_EXEC, |
| MAP_FIXED | MAP_SHARED, N_TXTOFF(ex)); |
| - if (error != 0) { |
| + |
| + if (error != N_TXTADDR(ex)) { |
| sys_close(fd); |
| send_sig(SIGSEGV, current, 0); |
| return 0; |
| }; |
| |
| - error = do_mmap(file, ex.a_text, ex.a_data, |
| + error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data, |
| PROT_READ | PROT_WRITE | PROT_EXEC, |
| MAP_FIXED | MAP_PRIVATE, N_TXTOFF(ex) + ex.a_text); |
| sys_close(fd); |
| - if (error != ex.a_text) { |
| + if (error != N_TXTADDR(ex) + ex.a_text) { |
| send_sig(SIGSEGV, current, 0); |
| return 0; |
| }; |
| @@ -818,6 +834,8 @@ |
| return -ENOEXEC; |
| } |
| |
| + if (N_FLAGS(ex)) return -ENOEXEC; |
| + |
| /* Now use mmap to map the library into memory. */ |
| error = do_mmap(file, ex.a_entry, ex.a_text + ex.a_data, |
| PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, |
| diff -u --recursive --new-files pl12/linux/fs/ext2/namei.c linux/fs/ext2/namei.c |
| --- pl12/linux/fs/ext2/namei.c Thu Aug 12 20:54:00 1993 |
| +++ linux/fs/ext2/namei.c Thu Aug 19 10:04:52 1993 |
| @@ -937,6 +937,8 @@ |
| new_inode->i_nlink--; |
| new_inode->i_dirt = 1; |
| } |
| + old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; |
| + old_dir->i_dirt = 1; |
| old_bh->b_dirt = 1; |
| new_bh->b_dirt = 1; |
| if (dir_bh) { |
| diff -u --recursive --new-files pl12/linux/fs/file_table.c linux/fs/file_table.c |
| --- pl12/linux/fs/file_table.c Mon Aug 9 17:41:22 1993 |
| +++ linux/fs/file_table.c Tue Aug 17 18:32:13 1993 |
| @@ -45,7 +45,7 @@ |
| struct file * file; |
| int i; |
| |
| - file = (struct file*) __get_free_page(GFP_BUFFER); |
| + file = (struct file *) get_free_page(GFP_KERNEL); |
| |
| if (!file) |
| return; |
| diff -u --recursive --new-files pl12/linux/fs/inode.c linux/fs/inode.c |
| --- pl12/linux/fs/inode.c Mon Aug 9 17:41:22 1993 |
| +++ linux/fs/inode.c Tue Aug 17 18:41:05 1993 |
| @@ -87,7 +87,7 @@ |
| struct inode * inode; |
| int i; |
| |
| - if(!(inode = (struct inode*) get_free_page(GFP_KERNEL))) |
| + if (!(inode = (struct inode*) get_free_page(GFP_KERNEL))) |
| return; |
| |
| i=PAGE_SIZE / sizeof(struct inode); |
| diff -u --recursive --new-files pl12/linux/fs/namei.c linux/fs/namei.c |
| --- pl12/linux/fs/namei.c Mon Aug 9 18:02:29 1993 |
| +++ linux/fs/namei.c Tue Aug 17 23:40:11 1993 |
| @@ -266,7 +266,7 @@ |
| * |
| * namei for open - this is in fact almost the whole open-routine. |
| * |
| - * Note that the low bits of "flag" aren't the same asin the open |
| + * Note that the low bits of "flag" aren't the same as in the open |
| * system call - they are 00 - no permissions needed |
| * 01 - read permission needed |
| * 10 - write permission needed |
| @@ -376,6 +376,16 @@ |
| } |
| } |
| } |
| + if (flag & O_TRUNC) { |
| + inode->i_size = 0; |
| + if (inode->i_op && inode->i_op->truncate) |
| + inode->i_op->truncate(inode); |
| + if ((error = notify_change(NOTIFY_SIZE, inode))) { |
| + iput(inode); |
| + return error; |
| + } |
| + inode->i_dirt = 1; |
| + } |
| *res_inode = inode; |
| return 0; |
| } |
| diff -u --recursive --new-files pl12/linux/fs/nfs/mmap.c linux/fs/nfs/mmap.c |
| --- pl12/linux/fs/nfs/mmap.c Sun Aug 15 11:46:03 1993 |
| +++ linux/fs/nfs/mmap.c Sat Aug 21 10:31:31 1993 |
| @@ -50,11 +50,9 @@ |
| { |
| struct vm_area_struct * mpnt; |
| |
| - if (off & (inode->i_sb->s_blocksize - 1)) |
| + if (prot & PAGE_RW) /* only PAGE_COW or read-only supported now */ |
| return -EINVAL; |
| - if (len > high_memory || off > high_memory - len) /* avoid overflow */ |
| - return -ENXIO; |
| - if (get_limit(USER_DS) != TASK_SIZE) |
| + if (off & (inode->i_sb->s_blocksize - 1)) |
| return -EINVAL; |
| if (!inode->i_sb || !S_ISREG(inode->i_mode)) |
| return -EACCES; |
| @@ -79,10 +77,6 @@ |
| mpnt->vm_ops = &nfs_file_mmap; |
| mpnt->vm_next = current->mmap; |
| current->mmap = mpnt; |
| -#if 0 |
| - printk("VFS: Loaded mmap at %08x - %08x\n", |
| - mpnt->vm_start, mpnt->vm_end); |
| -#endif |
| return 0; |
| } |
| |
| diff -u --recursive --new-files pl12/linux/fs/open.c linux/fs/open.c |
| --- pl12/linux/fs/open.c Mon Aug 9 18:02:29 1993 |
| +++ linux/fs/open.c Tue Aug 17 23:40:11 1993 |
| @@ -378,18 +378,7 @@ |
| f->f_count--; |
| return error; |
| } |
| - if (flag & O_TRUNC) { |
| - inode->i_size = 0; |
| - if (inode->i_op && inode->i_op->truncate) |
| - inode->i_op->truncate(inode); |
| - if ((error = notify_change(NOTIFY_SIZE, inode))) { |
| - iput(inode); |
| - current->filp[fd] = NULL; |
| - f->f_count--; |
| - return error; |
| - } |
| - inode->i_dirt = 1; |
| - } |
| + |
| f->f_inode = inode; |
| f->f_pos = 0; |
| f->f_reada = 0; |
| diff -u --recursive --new-files pl12/linux/fs/proc/array.c linux/fs/proc/array.c |
| --- pl12/linux/fs/proc/array.c Mon Aug 9 18:02:29 1993 |
| +++ linux/fs/proc/array.c Fri Aug 20 09:40:57 1993 |
| @@ -194,7 +194,7 @@ |
| if (vsize) { |
| eip = KSTK_EIP(vsize); |
| esp = KSTK_ESP(vsize); |
| - vsize = (*p)->brk + PAGE_SIZE-1; |
| + vsize = (*p)->brk - (*p)->start_code + PAGE_SIZE-1; |
| if (esp) |
| vsize += TASK_SIZE - esp; |
| } |
| @@ -264,7 +264,7 @@ |
| return 0; |
| tpag = (*p)->end_code / PAGE_SIZE; |
| if ((*p)->state != TASK_ZOMBIE) { |
| - pagedir = PAGE_DIR_OFFSET((*p)->tss.cr3,(*p)->start_code); |
| + pagedir = (unsigned long *) (*p)->tss.cr3; |
| for (i = 0; i < 0x300; ++i) { |
| if ((ptbl = pagedir[i]) == 0) { |
| tpag -= PTRS_PER_PAGE; |
| diff -u --recursive --new-files pl12/linux/include/linux/a.out.h linux/include/linux/a.out.h |
| --- pl12/linux/include/linux/a.out.h Mon Aug 9 17:41:23 1993 |
| +++ linux/include/linux/a.out.h Fri Aug 20 08:59:31 1993 |
| @@ -71,24 +71,26 @@ |
| #define NMAGIC 0410 |
| /* Code indicating demand-paged executable. */ |
| #define ZMAGIC 0413 |
| +/* This indicates a demand-paged executable with the header in the text. |
| + The first page is unmapped to help trap NULL pointer references */ |
| +#define QMAGIC 0314 |
| |
| /* Code indicating core file. */ |
| #define CMAGIC 0421 |
| + |
| #if !defined (N_BADMAG) |
| -#define N_BADMAG(x) \ |
| - (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \ |
| - && N_MAGIC(x) != ZMAGIC) |
| +#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ |
| + && N_MAGIC(x) != NMAGIC \ |
| + && N_MAGIC(x) != ZMAGIC \ |
| + && N_MAGIC(x) != QMAGIC) |
| #endif |
| |
| -#define _N_BADMAG(x) \ |
| - (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \ |
| - && N_MAGIC(x) != ZMAGIC) |
| - |
| #define _N_HDROFF(x) (1024 - sizeof (struct exec)) |
| |
| #if !defined (N_TXTOFF) |
| #define N_TXTOFF(x) \ |
| - (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec)) |
| + (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \ |
| + (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec))) |
| #endif |
| |
| #if !defined (N_DATOFF) |
| @@ -113,7 +115,7 @@ |
| |
| /* Address of text segment in memory after it is loaded. */ |
| #if !defined (N_TXTADDR) |
| -#define N_TXTADDR(x) 0 |
| +#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0) |
| #endif |
| |
| /* Address of data segment in memory after it is loaded. |
| diff -u --recursive --new-files pl12/linux/include/linux/binfmts.h linux/include/linux/binfmts.h |
| --- pl12/linux/include/linux/binfmts.h Fri Aug 6 13:32:00 1993 |
| +++ linux/include/linux/binfmts.h Fri Aug 20 08:59:31 1993 |
| @@ -15,6 +15,7 @@ |
| char buf[128]; |
| unsigned long page[MAX_ARG_PAGES]; |
| unsigned long p; |
| + int sh_bang; |
| struct inode * inode; |
| int e_uid, e_gid; |
| int argc, envc; |
| @@ -31,6 +32,15 @@ |
| |
| extern struct linux_binfmt formats[]; |
| |
| +extern int read_exec(struct inode *inode, unsigned long offset, |
| + char * addr, unsigned long count); |
| |
| +extern int open_inode(struct inode * inode, int mode); |
| + |
| +extern void flush_old_exec(struct linux_binprm * bprm); |
| +extern unsigned long change_ldt(unsigned long text_size,unsigned long * page); |
| +extern unsigned long * create_tables(char * p,int argc,int envc); |
| +extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page, |
| + unsigned long p, int from_kmem); |
| |
| #endif |
| diff -u --recursive --new-files pl12/linux/include/linux/elf.h linux/include/linux/elf.h |
| --- pl12/linux/include/linux/elf.h |
| +++ linux/include/linux/elf.h Fri Aug 20 08:59:31 1993 |
| @@ -0,0 +1,306 @@ |
| +#ifndef _ELF_H |
| +#define _ELF_H |
| + |
| +/* THese constants are for the segment types stored in the image headers */ |
| +#define PT_NULL 0 |
| +#define PT_LOAD 1 |
| +#define PT_DYNAMIC 2 |
| +#define PT_INTERP 3 |
| +#define PT_NOTE 4 |
| +#define PT_SHLIB 5 |
| +#define PT_PHDR 6 |
| +#define PT_LOPROC 0x70000000 |
| +#define PT_HIPROC 0x7fffffff |
| + |
| +/* These constants define the different elf file types */ |
| +#define ET_NONE 0 |
| +#define ET_REL 1 |
| +#define ET_EXEC 2 |
| +#define ET_DYN 3 |
| +#define ET_CORE 4 |
| +#define ET_LOPROC 5 |
| +#define ET_HIPROC 6 |
| + |
| +/* These constants define the various ELF target machines */ |
| +#define EM_NONE 0 |
| +#define EM_M32 1 |
| +#define EM_SPARC 2 |
| +#define EM_386 3 |
| +#define EM_68K 4 |
| +#define EM_88K 5 |
| +#define EM_486 6 /* Perhaps disused */ |
| +#define EM_860 7 |
| + |
| +/* This is the info that is needed to parse the dynamic section of the file */ |
| +#define DT_NULL 0 |
| +#define DT_NEEDED 1 |
| +#define DT_PLTRELSZ 2 |
| +#define DT_PLTGOT 3 |
| +#define DT_HASH 4 |
| +#define DT_STRTAB 5 |
| +#define DT_SYMTAB 6 |
| +#define DT_RELA 7 |
| +#define DT_RELASZ 8 |
| +#define DT_RELAENT 9 |
| +#define DT_STRSZ 10 |
| +#define DT_SYMENT 11 |
| +#define DT_INIT 12 |
| +#define DT_FINI 13 |
| +#define DT_SONAME 14 |
| +#define DT_RPATH 15 |
| +#define DT_SYMBOLIC 16 |
| +#define DT_REL 17 |
| +#define DT_RELSZ 18 |
| +#define DT_RELENT 19 |
| +#define DT_PLTREL 20 |
| +#define DT_DEBUG 21 |
| +#define DT_TEXTREL 22 |
| +#define DT_JMPREL 23 |
| +#define DT_LOPROC 0x70000000 |
| +#define DT_HIPROC 0x7fffffff |
| + |
| +/* This info is needed when parsing the symbol table */ |
| +#define STB_LOCAL 0 |
| +#define STB_GLOBAL 1 |
| +#define STB_WEAK 2 |
| + |
| +#define STT_NOTYPE 0 |
| +#define STT_OBJECT 1 |
| +#define STT_FUNC 2 |
| +#define STT_SECTION 3 |
| +#define STT_FILE 4 |
| + |
| +#define ELF32_ST_BIND(x) ((x) >> 4) |
| +#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) |
| + |
| + |
| + |
| +struct dynamic{ |
| + int d_tag; |
| + union{ |
| + int d_val; |
| + char * d_ptr; |
| + } d_un; |
| +}; |
| + |
| +/* THe following are used with relocations */ |
| +#define ELF32_R_SYM(x) ((x) >> 8) |
| +#define ELF32_R_TYPE(x) ((x) & 0xff) |
| + |
| +#define R_386_NONE 0 |
| +#define R_386_32 1 |
| +#define R_386_PC32 2 |
| +#define R_386_GOT32 3 |
| +#define R_386_PLT32 4 |
| +#define R_386_COPY 5 |
| +#define R_386_GLOB_DAT 6 |
| +#define R_386_JMP_SLOT 7 |
| +#define R_386_RELATIVE 8 |
| +#define R_386_GOTOFF 9 |
| +#define R_386_GOTPC 10 |
| +#define R_386_NUM 11 |
| + |
| +struct Elf32_Rel{ |
| + unsigned int * offset; |
| + int info; |
| +}; |
| + |
| +struct Elf32_Rela{ |
| + unsigned int * offset; |
| + int info; |
| + int addend; |
| +}; |
| + |
| +struct Elf32_Sym{ |
| + int st_name; |
| + unsigned int st_value; |
| + int st_size; |
| + unsigned char st_info; |
| + unsigned char st_other; |
| + short int st_shndx; |
| +}; |
| + |
| +struct elfhdr{ |
| + char e_ident[16]; |
| + short int e_type; |
| + short int e_machine; |
| + int e_version; |
| + char *e_entry; /* Entry point */ |
| + int e_phoff; |
| + int e_shoff; |
| + int e_flags; |
| + short int e_ehsize; |
| + short int e_phentsize; |
| + short int e_phnum; |
| + short int e_shentsize; |
| + short int e_shnum; |
| + short int e_shstrndx; |
| +}; |
| + |
| +struct elf_phdr{ |
| + int p_type; |
| + int p_offset; |
| + int p_vaddr; |
| + int p_paddr; |
| + int p_filesz; |
| + int p_memsz; |
| + int p_flags; |
| + int p_align; |
| +}; |
| + |
| +#define ELF_START_MMAP 0x80000000 |
| + |
| +#endif |
| +#ifndef _ELF_H |
| +#define _ELF_H |
| + |
| +/* THese constants are for the segment types stored in the image headers */ |
| +#define PT_NULL 0 |
| +#define PT_LOAD 1 |
| +#define PT_DYNAMIC 2 |
| +#define PT_INTERP 3 |
| +#define PT_NOTE 4 |
| +#define PT_SHLIB 5 |
| +#define PT_PHDR 6 |
| +#define PT_LOPROC 0x70000000 |
| +#define PT_HIPROC 0x7fffffff |
| + |
| +/* These constants define the different elf file types */ |
| +#define ET_NONE 0 |
| +#define ET_REL 1 |
| +#define ET_EXEC 2 |
| +#define ET_DYN 3 |
| +#define ET_CORE 4 |
| +#define ET_LOPROC 5 |
| +#define ET_HIPROC 6 |
| + |
| +/* These constants define the various ELF target machines */ |
| +#define EM_NONE 0 |
| +#define EM_M32 1 |
| +#define EM_SPARC 2 |
| +#define EM_386 3 |
| +#define EM_68K 4 |
| +#define EM_88K 5 |
| +#define EM_486 6 /* Perhaps disused */ |
| +#define EM_860 7 |
| + |
| +/* This is the info that is needed to parse the dynamic section of the file */ |
| +#define DT_NULL 0 |
| +#define DT_NEEDED 1 |
| +#define DT_PLTRELSZ 2 |
| +#define DT_PLTGOT 3 |
| +#define DT_HASH 4 |
| +#define DT_STRTAB 5 |
| +#define DT_SYMTAB 6 |
| +#define DT_RELA 7 |
| +#define DT_RELASZ 8 |
| +#define DT_RELAENT 9 |
| +#define DT_STRSZ 10 |
| +#define DT_SYMENT 11 |
| +#define DT_INIT 12 |
| +#define DT_FINI 13 |
| +#define DT_SONAME 14 |
| +#define DT_RPATH 15 |
| +#define DT_SYMBOLIC 16 |
| +#define DT_REL 17 |
| +#define DT_RELSZ 18 |
| +#define DT_RELENT 19 |
| +#define DT_PLTREL 20 |
| +#define DT_DEBUG 21 |
| +#define DT_TEXTREL 22 |
| +#define DT_JMPREL 23 |
| +#define DT_LOPROC 0x70000000 |
| +#define DT_HIPROC 0x7fffffff |
| + |
| +/* This info is needed when parsing the symbol table */ |
| +#define STB_LOCAL 0 |
| +#define STB_GLOBAL 1 |
| +#define STB_WEAK 2 |
| + |
| +#define STT_NOTYPE 0 |
| +#define STT_OBJECT 1 |
| +#define STT_FUNC 2 |
| +#define STT_SECTION 3 |
| +#define STT_FILE 4 |
| + |
| +#define ELF32_ST_BIND(x) ((x) >> 4) |
| +#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) |
| + |
| + |
| + |
| +struct dynamic{ |
| + int d_tag; |
| + union{ |
| + int d_val; |
| + char * d_ptr; |
| + } d_un; |
| +}; |
| + |
| +/* THe following are used with relocations */ |
| +#define ELF32_R_SYM(x) ((x) >> 8) |
| +#define ELF32_R_TYPE(x) ((x) & 0xff) |
| + |
| +#define R_386_NONE 0 |
| +#define R_386_32 1 |
| +#define R_386_PC32 2 |
| +#define R_386_GOT32 3 |
| +#define R_386_PLT32 4 |
| +#define R_386_COPY 5 |
| +#define R_386_GLOB_DAT 6 |
| +#define R_386_JMP_SLOT 7 |
| +#define R_386_RELATIVE 8 |
| +#define R_386_GOTOFF 9 |
| +#define R_386_GOTPC 10 |
| +#define R_386_NUM 11 |
| + |
| +struct Elf32_Rel{ |
| + unsigned int * offset; |
| + int info; |
| +}; |
| + |
| +struct Elf32_Rela{ |
| + unsigned int * offset; |
| + int info; |
| + int addend; |
| +}; |
| + |
| +struct Elf32_Sym{ |
| + int st_name; |
| + unsigned int st_value; |
| + int st_size; |
| + unsigned char st_info; |
| + unsigned char st_other; |
| + short int st_shndx; |
| +}; |
| + |
| +struct elfhdr{ |
| + char e_ident[16]; |
| + short int e_type; |
| + short int e_machine; |
| + int e_version; |
| + char *e_entry; /* Entry point */ |
| + int e_phoff; |
| + int e_shoff; |
| + int e_flags; |
| + short int e_ehsize; |
| + short int e_phentsize; |
| + short int e_phnum; |
| + short int e_shentsize; |
| + short int e_shnum; |
| + short int e_shstrndx; |
| +}; |
| + |
| +struct elf_phdr{ |
| + int p_type; |
| + int p_offset; |
| + int p_vaddr; |
| + int p_paddr; |
| + int p_filesz; |
| + int p_memsz; |
| + int p_flags; |
| + int p_align; |
| +}; |
| + |
| +#define ELF_START_MMAP 0x80000000 |
| + |
| +#endif |
| diff -u --recursive --new-files pl12/linux/include/linux/signal.h linux/include/linux/signal.h |
| --- pl12/linux/include/linux/signal.h Thu May 20 10:34:30 1993 |
| +++ linux/include/linux/signal.h Mon Aug 16 18:55:12 1993 |
| @@ -53,6 +53,9 @@ |
| */ |
| #define SIGPWR 30 |
| |
| +/* Arggh. Bad user source code wants this.. */ |
| +#define SIGBUS SIGUNUSED |
| + |
| /* |
| * sa_flags values: SA_STACK is not currently supported, but will allow the |
| * usage of signal stacks by using the (now obsolete) sa_restorer field in |
| diff -u --recursive --new-files pl12/linux/include/linux/tasks.h linux/include/linux/tasks.h |
| --- pl12/linux/include/linux/tasks.h Mon Jan 18 22:06:34 1993 |
| +++ linux/include/linux/tasks.h Wed Aug 18 23:05:21 1993 |
| @@ -4,6 +4,6 @@ |
| /* |
| * This is the maximum nr of tasks - change it if you need to |
| */ |
| -#define NR_TASKS 64 |
| +#define NR_TASKS 128 |
| |
| #endif |
| diff -u --recursive --new-files pl12/linux/include/linux/timer.h linux/include/linux/timer.h |
| --- pl12/linux/include/linux/timer.h Sat Aug 14 23:47:22 1993 |
| +++ linux/include/linux/timer.h Tue Aug 17 18:39:34 1993 |
| @@ -17,6 +17,8 @@ |
| * |
| * HD_TIMER harddisk timer |
| * |
| + * HD_TIMER2 (atdisk2 patches) |
| + * |
| * FLOPPY_TIMER floppy disk timer (not used right now) |
| * |
| * SCSI_TIMER scsi.c timeout timer |
| @@ -43,6 +45,8 @@ |
| |
| #define TAPE_QIC02_TIMER 22 /* hhb */ |
| #define MCD_TIMER 23 |
| + |
| +#define HD_TIMER2 24 |
| |
| struct timer_struct { |
| unsigned long expires; |
| diff -u --recursive --new-files pl12/linux/kernel/chr_drv/keyboard.c linux/kernel/chr_drv/keyboard.c |
| --- pl12/linux/kernel/chr_drv/keyboard.c Sat Aug 14 18:52:34 1993 |
| +++ linux/kernel/chr_drv/keyboard.c Thu Aug 19 18:45:38 1993 |
| @@ -584,6 +584,8 @@ |
| value = KVAL(K_SHIFT); |
| clr_vc_kbd_flag(kbd, VC_CAPSLOCK); |
| } |
| + if (value > 3) |
| + return; |
| |
| if (up_flag) { |
| if (k_down[value]) |
| diff -u --recursive --new-files pl12/linux/kernel/chr_drv/mem.c linux/kernel/chr_drv/mem.c |
| --- pl12/linux/kernel/chr_drv/mem.c Mon Aug 9 18:02:32 1993 |
| +++ linux/kernel/chr_drv/mem.c Sat Aug 21 10:19:32 1993 |
| @@ -129,12 +129,28 @@ |
| static int mmap_mem(struct inode * inode, struct file * file, |
| unsigned long addr, size_t len, int prot, unsigned long off) |
| { |
| + struct vm_area_struct * mpnt; |
| + |
| if (off & 0xfff || off + len < off) |
| return -ENXIO; |
| - |
| if (remap_page_range(addr, off, len, prot)) |
| return -EAGAIN; |
| - |
| +/* try to create a dummy vmm-structure so that the rest of the kernel knows we are here */ |
| + mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL); |
| + if (!mpnt) |
| + return 0; |
| + |
| + mpnt->vm_task = current; |
| + mpnt->vm_start = addr; |
| + mpnt->vm_end = addr + len; |
| + mpnt->vm_page_prot = prot; |
| + mpnt->vm_share = NULL; |
| + mpnt->vm_inode = inode; |
| + inode->i_count++; |
| + mpnt->vm_offset = off; |
| + mpnt->vm_ops = NULL; |
| + mpnt->vm_next = current->mmap; |
| + current->mmap = mpnt; |
| return 0; |
| } |
| |
| diff -u --recursive --new-files pl12/linux/kernel/chr_drv/serial.c linux/kernel/chr_drv/serial.c |
| --- pl12/linux/kernel/chr_drv/serial.c Fri Aug 13 21:20:52 1993 |
| +++ linux/kernel/chr_drv/serial.c Wed Aug 18 01:13:23 1993 |
| @@ -1321,12 +1321,10 @@ |
| |
| switch (cmd) { |
| case TCSBRK: /* SVID version: non-zero arg --> no break */ |
| - wait_until_sent(tty); |
| if (!arg) |
| send_break(info, HZ/4); /* 1/4 second */ |
| return 0; |
| case TCSBRKP: /* support for POSIX tcsendbreak() */ |
| - wait_until_sent(tty); |
| send_break(info, arg ? arg*(HZ/10) : HZ/4); |
| return 0; |
| case TIOCGSOFTCAR: |
| diff -u --recursive --new-files pl12/linux/kernel/chr_drv/tty_ioctl.c linux/kernel/chr_drv/tty_ioctl.c |
| --- pl12/linux/kernel/chr_drv/tty_ioctl.c Thu Jul 29 12:15:25 1993 |
| +++ linux/kernel/chr_drv/tty_ioctl.c Wed Aug 18 01:13:07 1993 |
| @@ -605,7 +605,12 @@ |
| tty->packet = 0; |
| return (0); |
| } |
| - |
| + case TCSBRK: case TCSBRKP: |
| + wait_until_sent(tty); |
| + if (!tty->ioctl) |
| + return 0; |
| + tty->ioctl(tty, file, cmd, arg); |
| + return 0; |
| default: |
| if (tty->ioctl) { |
| retval = (tty->ioctl)(tty, file, cmd, arg); |
| diff -u --recursive --new-files pl12/linux/kernel/exit.c linux/kernel/exit.c |
| --- pl12/linux/kernel/exit.c Mon Aug 2 18:16:26 1993 |
| +++ linux/kernel/exit.c Sat Aug 21 11:14:59 1993 |
| @@ -376,7 +376,7 @@ |
| current->mmap = NULL; |
| while (mpnt) { |
| mpnt1 = mpnt->vm_next; |
| - if (mpnt->vm_ops->close) |
| + if (mpnt->vm_ops && mpnt->vm_ops->close) |
| mpnt->vm_ops->close(mpnt); |
| kfree(mpnt); |
| mpnt = mpnt1; |
| diff -u --recursive --new-files pl12/linux/kernel/signal.c linux/kernel/signal.c |
| --- pl12/linux/kernel/signal.c Sun Aug 15 14:28:14 1993 |
| +++ linux/kernel/signal.c Sat Aug 21 10:38:00 1993 |
| @@ -22,6 +22,31 @@ |
| |
| extern "C" int do_signal(unsigned long oldmask, struct pt_regs * regs); |
| |
| +struct sigcontext_struct { |
| + unsigned short gs, __gsh; |
| + unsigned short fs, __fsh; |
| + unsigned short es, __esh; |
| + unsigned short ds, __dsh; |
| + unsigned long edi; |
| + unsigned long esi; |
| + unsigned long ebp; |
| + unsigned long esp; |
| + unsigned long ebx; |
| + unsigned long edx; |
| + unsigned long ecx; |
| + unsigned long eax; |
| + unsigned long trapno; |
| + unsigned long err; |
| + unsigned long eip; |
| + unsigned short cs, __csh; |
| + unsigned long eflags; |
| + unsigned long esp_at_signal; |
| + unsigned short ss, __ssh; |
| + unsigned long i387; |
| + unsigned long oldmask; |
| + unsigned long cr2; |
| +}; |
| + |
| extern "C" int sys_sgetmask(void) |
| { |
| return current->blocked; |
| @@ -151,15 +176,32 @@ |
| /* |
| * This sets regs->esp even though we don't actually use sigstacks yet.. |
| */ |
| -extern "C" int sys_sigreturn(unsigned long oldmask, unsigned long eip, unsigned long esp) |
| +extern "C" int sys_sigreturn(unsigned long __unused) |
| { |
| +#define CHECK_SEG(x) if (x) x |= 3 |
| +#define COPY(x) regs->x = context.x |
| + struct sigcontext_struct context; |
| struct pt_regs * regs; |
| |
| - regs = (struct pt_regs *) &oldmask; |
| - current->blocked = oldmask & _BLOCKABLE; |
| - regs->eip = eip; |
| - regs->esp = esp; |
| - return 0; |
| + regs = (struct pt_regs *) &__unused; |
| + memcpy_fromfs(&context,(void *) regs->esp, sizeof(context)); |
| + current->blocked = context.oldmask & _BLOCKABLE; |
| + CHECK_SEG(context.ss); |
| + CHECK_SEG(context.cs); |
| + CHECK_SEG(context.ds); |
| + CHECK_SEG(context.es); |
| + CHECK_SEG(context.fs); |
| + CHECK_SEG(context.gs); |
| + COPY(eip); COPY(eflags); |
| + COPY(ecx); COPY(edx); |
| + COPY(ebx); |
| + COPY(esp); COPY(ebp); |
| + COPY(edi); COPY(esi); |
| + COPY(cs); COPY(ss); |
| + COPY(ds); COPY(es); |
| + COPY(fs); COPY(gs); |
| + regs->orig_eax = -1; /* disable syscall checks */ |
| + return context.eax; |
| } |
| |
| /* |
| @@ -186,32 +228,26 @@ |
| put_fs_long(regs->edi, frame+6); |
| put_fs_long(regs->esi, frame+7); |
| put_fs_long(regs->ebp, frame+8); |
| - put_fs_long(regs->esp, frame+9); |
| + put_fs_long((long)*fp, frame+9); |
| put_fs_long(regs->ebx, frame+10); |
| put_fs_long(regs->edx, frame+11); |
| put_fs_long(regs->ecx, frame+12); |
| put_fs_long(regs->eax, frame+13); |
| - put_fs_long(0, frame+14); /* trapno */ |
| - put_fs_long(0, frame+15); /* err */ |
| - put_fs_long(regs->eip, frame+16); |
| + put_fs_long(0, frame+14); /* trapno - not implemented */ |
| + put_fs_long(0, frame+15); /* err - not implemented */ |
| + put_fs_long(eip, frame+16); |
| put_fs_long(regs->cs, frame+17); |
| put_fs_long(regs->eflags, frame+18); |
| put_fs_long(regs->esp, frame+19); |
| put_fs_long(regs->ss, frame+20); |
| - put_fs_long(0,frame+21); /* 387 state pointer */ |
| -/* linux extended stack - easier to handle.. */ |
| - put_fs_long(regs->eflags, frame+22); |
| - put_fs_long(eip, frame+23); |
| + put_fs_long(0,frame+21); /* 387 state pointer - not implemented*/ |
| +/* non-iBCS2 extensions.. */ |
| + put_fs_long(oldmask, frame+22); |
| + put_fs_long(0, frame+23); /* cr2 - not implemented */ |
| /* set up the return code... */ |
| put_fs_long(0x0000b858, CODE(0)); /* popl %eax ; movl $,%eax */ |
| - put_fs_long(0x00bb0000, CODE(4)); /* movl $,%ebx */ |
| - put_fs_long(0xcd000000, CODE(8)); /* int $0x80 */ |
| - put_fs_long(0x0fa90f80, CODE(12)); /* pop %gs ; pop %fs */ |
| - put_fs_long(0x611f07a1, CODE(16)); /* pop %es ; pop %ds ; popad */ |
| - put_fs_long(0x20c48390, CODE(20)); /* nop ; addl $32,%esp */ |
| - put_fs_long(0x0020c29d, CODE(24)); /* popfl ; ret $32 */ |
| - put_fs_long(__NR_ssetmask, CODE(2)); |
| - put_fs_long(oldmask, CODE(7)); |
| + put_fs_long(0x80cd0000, CODE(4)); /* int $0x80 */ |
| + put_fs_long(__NR_sigreturn, CODE(2)); |
| *fp = frame; |
| #undef __CODE |
| #undef CODE |
| @@ -317,8 +353,8 @@ |
| frame = (unsigned long *) regs->esp; |
| signr = 1; |
| sa = current->sigaction; |
| - if (regs->cs != USER_CS || regs->ss != USER_DS) |
| - printk("Warning: signal handler with nonstandard code/stack segment\n"); |
| + if (regs->ss != USER_DS) |
| + printk("Warning: signal handler with nonstandard stack segment\n"); |
| for (mask = 1 ; mask ; sa++,signr++,mask += mask) { |
| if (mask > handler_signal) |
| break; |
| @@ -331,6 +367,9 @@ |
| __asm__("testb $0,%%fs:%0": :"m" (*(char *) sa_handler)); |
| setup_frame(&frame,eip,regs,signr,sa_handler,oldmask); |
| eip = sa_handler; |
| + regs->cs = USER_CS; regs->ss = USER_DS; |
| + regs->ds = USER_DS; regs->es = USER_DS; |
| + regs->gs = USER_DS; regs->fs = USER_DS; |
| current->blocked |= sa->sa_mask; |
| oldmask |= sa->sa_mask; |
| } |
| diff -u --recursive --new-files pl12/linux/mm/memory.c linux/mm/memory.c |
| --- pl12/linux/mm/memory.c Sun Aug 15 11:09:18 1993 |
| +++ linux/mm/memory.c Sat Aug 21 10:23:07 1993 |
| @@ -760,7 +760,7 @@ |
| { |
| struct task_struct ** p; |
| |
| - if (!inode || inode->i_count < 2) |
| + if (!inode || inode->i_count < 2 || !area->vm_ops) |
| return 0; |
| for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { |
| if (!*p) |
| @@ -773,8 +773,8 @@ |
| we can share pages with */ |
| if(area){ |
| struct vm_area_struct * mpnt; |
| - for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next){ |
| - if(mpnt->vm_ops && mpnt->vm_ops == area->vm_ops && |
| + for (mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) { |
| + if (mpnt->vm_ops == area->vm_ops && |
| mpnt->vm_inode->i_ino == area->vm_inode->i_ino&& |
| mpnt->vm_inode->i_dev == area->vm_inode->i_dev){ |
| if (mpnt->vm_ops->share(mpnt, area, address)) |
| @@ -851,6 +851,8 @@ |
| continue; |
| if (address >= ((mpnt->vm_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) |
| continue; |
| + if (!mpnt->vm_ops || !mpnt->vm_ops->nopage) |
| + break; |
| mpnt->vm_ops->nopage(error_code, mpnt, address); |
| return; |
| } |
| @@ -858,7 +860,7 @@ |
| get_empty_page(tsk,address); |
| if (tsk != current) |
| return; |
| - if (address < tsk->brk) |
| + if (address >= tsk->end_data && address < tsk->brk) |
| return; |
| if (address+8192 >= (user_esp & 0xfffff000) && |
| address <= current->start_stack) |
| diff -u --recursive --new-files pl12/linux/mm/mmap.c linux/mm/mmap.c |
| --- pl12/linux/mm/mmap.c Mon Aug 9 18:02:33 1993 |
| +++ linux/mm/mmap.c Sat Aug 21 11:37:00 1993 |
| @@ -52,11 +52,11 @@ |
| switch (flags & MAP_TYPE) { |
| case MAP_SHARED: |
| if ((prot & PROT_WRITE) && !(file->f_mode & 2)) |
| - return -EINVAL; |
| + return -EACCES; |
| /* fall through */ |
| case MAP_PRIVATE: |
| if (!(file->f_mode & 1)) |
| - return -EINVAL; |
| + return -EACCES; |
| break; |
| |
| default: |
| @@ -169,7 +169,7 @@ |
| while (free) { |
| mpnt = free; |
| free = free->vm_next; |
| - if (mpnt->vm_ops->close) |
| + if (mpnt->vm_ops && mpnt->vm_ops->close) |
| mpnt->vm_ops->close(mpnt); |
| kfree(mpnt); |
| } |
| @@ -197,11 +197,9 @@ |
| extern struct vm_operations_struct file_mmap; |
| struct buffer_head * bh; |
| |
| - if (off & (inode->i_sb->s_blocksize - 1)) |
| + if (prot & PAGE_RW) /* only PAGE_COW or read-only supported right now */ |
| return -EINVAL; |
| - if (len > high_memory || off > high_memory - len) /* avoid overflow */ |
| - return -ENXIO; |
| - if (get_limit(USER_DS) != TASK_SIZE) |
| + if (off & (inode->i_sb->s_blocksize - 1)) |
| return -EINVAL; |
| if (!inode->i_sb || !S_ISREG(inode->i_mode)) |
| return -EACCES; |
| @@ -231,10 +229,6 @@ |
| mpnt->vm_ops = &file_mmap; |
| mpnt->vm_next = current->mmap; |
| current->mmap = mpnt; |
| -#if 0 |
| - printk("VFS: Loaded mmap at %08x - %08x\n", |
| - mpnt->vm_start, mpnt->vm_end); |
| -#endif |
| return 0; |
| } |
| |
| diff -u --recursive --new-files pl12/linux/net/inet/slip.c linux/net/inet/slip.c |
| --- pl12/linux/net/inet/slip.c Sat Jul 31 15:42:22 1993 |
| +++ linux/net/inet/slip.c Thu Aug 19 09:46:23 1993 |
| @@ -688,7 +688,7 @@ |
| if (already++ == 0) { |
| printk("SLIP: version %s (%d channels): ", |
| SLIP_VERSION, SL_NRUNIT); |
| - |
| + printk("CSLIP code copyright 1989 Regents of the University of California\n"); |
| /* Fill in our LDISC request block. */ |
| sl_ldisc.flags = 0; |
| sl_ldisc.open = slip_open; |