blob: 1bc93961f8f60a5ebc5ad3e3ff6ee7fe1c773377 [file] [log] [blame]
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;