| 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; |