Fri Sep 3 11:52:18 1993 Bob Amstadt * [windows/timer.c] Changed to use CallWindowProc() rather directly calling callback. * [windows/event.c] Implemented SetCapture() and ReleaseCapture() * [windows/keyboard.c] Created stub for GetKeyState() * [objects/linedda.c] Created stub for LineDDA() * [if1632/callback.c] Created callback handler for LineDDA callback procedure. * [if1632/callback.c] Created FreeProcInstance() Fri Sep 3 08:36:52 1993 David Metcalfe * [loader/signal.c] Patch to and code for INT 1A Thu Sep 2 00:31:54 1993 Alexandre Julliard * [objects/font.c] [objects/text.c] More text support: implemented justification and underlining. * [windows/clipping.c] [objects/clipping.c] Moved low-level clipping functions to objects/clipping.c. * [windows/clipping.c] [windows/event.c] [windows/message.c] Implemented window update regions. * [windows/dc.c] [objects/dcvalues.c] Moved some device-independent DC functions to objects/dcvalues.c. * [windows/graphics.c] Implemented InvertRect() and GetPixel(). Sat Aug 28 08:40:23 1993 Eric Youngdale * [include/neexe.h] [loader/wine.c] Added code to handle relocation type 4. * [loader/signal.h] [loader/wine.c] [loader/selector.c] Added support for dos interrupts. Thu 26 Aug 19:15:00 1993 Eric Youngdale * [loader/selector.c] Fixed bug dealing with loading DLLs. Thu Aug 26 19:22:40 1993 Alexandre Julliard * [include/gdi.h] [objects/font.c] [windows/dc.c] Beginning of real font support. * [windows/graphics.c] Implemented PatBlt(). * [memory/global.c] Corrected a bug with linked list handling in GlobalAlloc(). * [objects/bitmap.c] Corrected a bug in BITMAP_SelectObject(). Tue Aug 24 19:22:40 1993 David Metcalfe * [controls/Command*] [controls/Label*] [controls[MenuButto*] [controls/SmeMenuButt*] Change code to support & as a special character in menu item text. Tue Aug 24 19:22:40 1993 Alexandre Julliard * [include/gdi.h] [windows/dc.c] Heavily modified the DC structure for better device-independence. * [objects/bitmap.c] Implemented bitmap dimensions. * [windows/dc.c] [windows/dce.c] Implemented DC state saving and restoring. * [windows/dc.c] Implemented ROP mode. * [windows/graphics.c] Implemented FillRect(). Mon Aug 23 22:08:34 1993 Bob Amstadt (bob at pooh) * [misc/xt.c] Fixed bug in InvalidateRect(). Solitaire attempted to clear window before it was realized. * [loader/resource.c] Began rewrite of LoadBitmap(). * [loader/wine.c] Fixed code which set Argv and Argc global variables. * [loader/selector.c] Added code to set up command line arguments. * [include/neexe.h] Fixed error in PSP structure. Tue Aug 17 20:41:12 1993 Alexandre Julliard * [include/gdi.h] [windows/dc.c] Implemented device capabilities. * [objects/region.c] Implemented EqualRgn() and CombineRgn(). * [windows/clipping.c] Implemented Save/RestoreVisRgn(). * [windows/graphics.c] Implemented PaintRgn() and FillRgn(). * [windows/mapping.c] Implemented mapping modes. Tue Aug 10 14:07:38 1993 Alexandre Julliard * [if1632/user.spec] [misc/rect.c] Implemented rectangle API functions. * [if1632/gdi.spec] [include/gdi.h] [objects/region.c] Implemented regions. * [windows/class.c] Corrected a typo in UnregisterClass(). * [windows/clipping.c] [windows/dc.c] Implemented DC clipping and visible region. Tue Aug 10 20:57:56 1993 Bob Amstadt (bob at pooh) * [controls/menu.c] [windows/win.c] SetMenu(), GetMenu(), CheckMenuItem() implemented Thu Aug 5 22:33:22 1993 Bob Amstadt (bob at pooh) * [controls/menu.c] [windows/win.c] Many improvements menus. LoadMenu() should work. Wed Aug 4 14:55:36 1993 Alexandre Julliard * [objects/dib.c] Started the implementation of device-independent bitmaps. * [objects/bitmap.c] Added support for multiple bitmap depths. * [objects/brush.c] Implemented pattern brushes. * [windows/dc.c] [windows/graphics.c] Implemented some GDI graphics primitives. Tue Aug 3 21:16:47 1993 Bob Amstadt (bob at pooh) * [controls/menu.c] [windows/win.c] [include/menu.h] Code to load class menus from executable file. * [if1632/user.spec] Fixed specification of SendMessage() and PostMessage. Mon Jul 26 21:53:24 1993 Alexandre Julliard * [if1632/call.S] Corrected a bug in KERNEL_InitTask(). * [include/windows.h] Added a lot of constants. * [loader/selector.c] Corrected a bug in segment allocation in CreateSelectors(). * [objects/bitmap.c] Implemented SelectObject() for bitmaps. * [objects/brush.c] Implemented hatched brushes and SelectObject(). * [objects/gdiobj.c] Removed linked list (not needed). * [objects/palette.c] Implemented system palette creation and misc. palette API functions. * [windows/timer.c] Implemented timers. * [windows/dc.c] Implemented memory device contexts. Tue Jul 20 10:38:59 1993 Bob Amstadt (bob at pooh) * [dos.c] Split DOS3Call() out of kernel.c. Added support for get date and time functions. * [call.S] Added function ReturnFromRegisterFunc() to allow DOS calls to return values in registers. * [regfunc.h] Macros to access registers saved on stack. Tue Jul 20 10:38:59 1993 Alexandre Julliard * [win.c] Corrected allocation of the WM_CREATE data structure. * [dce.c] [dce.h] Implemented DCE handling. * [bitmap.c] [brush.c] [dc.c] [font.c] [gdi.h] [gdi.spec] [gdiobj.c] [palette.c] [pen.c] Implemented the GDI objects data structures and allocation. * [windows.h] Added several structures and constants for GDI objects. Mon Jul 19 12:51:10 1993 Bob Amstadt (bob at pooh) * [ldtlib.c] Modified system calls to match Linus' new interface for the LDT modification. * [win.c] Fixed bug with WM_CREATE message. * [heap.c] [kernel.spec] Completed local heap allocation functions. * [global.c] Created function GlobalQuickAlloc() for easy allocation from DLLs
1419 lines
39 KiB
Text
1419 lines
39 KiB
Text
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;
|