Johnie Ingram wrote:
> 
> "Juan" == Juan Cespedes <[EMAIL PROTECTED]> writes:
> 
> Juan>         I've investigated a bit, and I think this patch to the Linux
> Juan> Kernel should fix this problem:
> 
> Because I'm reluctant to change the kernel being used (its been up 40
> days), I modifed the glibc-sparc itself so that it uses the working
> call.

Nice ;-)

> Its at ftp://ftp1.us.debian.org/debian/local, if anyone else needs it.
> I couldn't complete the building of the libc6 .deb files because the
> compile segfaults in the sunrpc dir.  Apparently ld-linux.so.2 can't
> take programs to run on the command line.  :-(

You have to apply a patch to your kernel.  See the MIME attachment.

> At any rate ftp1.us.debian.org contains libc.so.6, the brilliant
> Anders Hammarquist fix to ld-linux.so.2, and ldso_1.9.6-2.deb (which
> has been uploaded).
> 
> Network daemons like apache and proftpd actually work now!!!!
> The ldd program actually shows dependencies!!

Hmm, ldso 1.9.6-2 don't work anymore on binaries linked with libc5 :-(
$ ldd /usr/local/redhat/bin/ncftp
ldd: /usr/local/redhat/bin/ncftp exited with signal 11

-- 
 Eric Delaunay                 | "La guerre justifie l'existence des militaires.
 [EMAIL PROTECTED] | En les supprimant." Henri Jeanson (1900-1970)
diff -ruNp sparclinux-stable/fs/binfmt_elf.c sls-rth/fs/binfmt_elf.c
--- sparclinux-stable/fs/binfmt_elf.c   Tue May 27 22:47:19 1997
+++ sls-rth/fs/binfmt_elf.c     Sun Jun 15 07:38:35 1997
@@ -119,15 +119,15 @@ unsigned long * create_elf_tables(char *
        /*
         * Force 16 byte alignment here for generality.
         */
-       sp = (unsigned long *) (~15UL & (unsigned long) p);
-#ifdef __sparc__
+       sp = (unsigned long *) (-sizeof(long) & (unsigned long)p);
        csp = sp;
        csp -= exec ? DLINFO_ITEMS*2 : 2;
        csp -= envc+1;
        csp -= argc+1;
-       if (!(((unsigned long) csp) & 4))
-               sp--;
-#endif
+       csp -= 1;  /* argc */
+       if ((unsigned long) csp & 15UL)
+               sp -= (16 - ((unsigned long) csp & 15UL)) / sizeof(long);
+
        sp -= exec ? DLINFO_ITEMS*2 : 2;
        dlinfo = sp;
        sp -= envc+1;
@@ -385,13 +385,13 @@ do_load_elf_binary(struct linux_binprm *
        struct file * file;
        struct exec interp_ex;
        struct inode *interpreter_inode;
-       unsigned long load_addr;
+       unsigned long load_addr, load_bias;
        int load_addr_set = 0;
        unsigned int interpreter_type = INTERPRETER_NONE;
        unsigned char ibcs2_interpreter;
        int i;
        int old_fs;
-       int error;
+       unsigned long error;
        struct elf_phdr * elf_ppnt, *elf_phdata;
        int elf_exec_fileno;
        unsigned long elf_bss, k, elf_brk;
@@ -405,7 +405,7 @@ do_load_elf_binary(struct linux_binprm *
        
        ibcs2_interpreter = 0;
        status = 0;
-       load_addr = 0;
+       load_addr = load_bias = 0;
        elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
        
        if (elf_ex.e_ident[0] != 0x7f ||
@@ -582,6 +582,19 @@ do_load_elf_binary(struct linux_binprm *
        bprm->p = setup_arg_pages(bprm->p, bprm);
        current->mm->start_stack = bprm->p;
        
+       /* Try and get dynamic programs out of the way of the default mmap
+          base, as well as whatever program they might try to "exec".
+          This is because the brk will follow the loader, and is not 
+          movable.  */
+
+       if (elf_ex.e_type == ET_DYN) {
+#ifdef __sparc__
+               load_bias = TASK_UNMAPPED_BASE - 0x10000000;
+#else
+               load_bias = 2 * TASK_SIZE / 3;
+#endif
+       }
+
        /* 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
@@ -591,29 +604,41 @@ do_load_elf_binary(struct linux_binprm *
        set_fs(get_ds());
        for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
                if (elf_ppnt->p_type == PT_LOAD) {
-                       int elf_prot = 0;
+                       int elf_flags, elf_prot = 0;
+                       unsigned long vaddr = 0;
+
                        if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
                        if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
                        if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
 
+                       elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
+
+                       if (elf_ex.e_type == ET_EXEC || load_addr_set) {
+                               vaddr = elf_ppnt->p_vaddr;
+                               elf_flags |= MAP_FIXED;
+                       }
+
                        error = do_mmap(file,
-                                       ELF_PAGESTART(elf_ppnt->p_vaddr),
+                                       ELF_PAGESTART(load_bias + vaddr),
                                        (elf_ppnt->p_filesz +
                                         ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
-                                       elf_prot,
-                                       (MAP_FIXED | MAP_PRIVATE |
-                                        MAP_DENYWRITE | MAP_EXECUTABLE),
+                                       elf_prot, elf_flags,
                                        (elf_ppnt->p_offset -
                                         ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
                        
 #ifdef LOW_ELF_STACK
-                       if (ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack) 
-                               elf_stack = ELF_PAGESTART(elf_ppnt->p_vaddr);
+                       if (error < elf_stack) 
+                               elf_stack = error-1;
 #endif
                        
                        if (!load_addr_set) { 
-                         load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
-                         load_addr_set = 1;
+                               load_addr_set = 1;
+                               load_addr = (elf_ppnt->p_vaddr -
+                                            elf_ppnt->p_offset);
+                               if (elf_ex.e_type == ET_DYN) {
+                                       load_bias = error;
+                                       load_addr += error;
+                               }
                        }
                        k = elf_ppnt->p_vaddr;
                        if (k < start_code) start_code = k;
@@ -632,6 +657,13 @@ do_load_elf_binary(struct linux_binprm *
        }
        set_fs(old_fs);
 
+       elf_entry += load_bias;
+       elf_bss += load_bias;
+       elf_brk += load_bias;
+       start_code += load_bias;
+       end_code += load_bias;
+       end_data += load_bias;
+
        if (elf_interpreter) {
                if (interpreter_type & 1) 
                        elf_entry = load_aout_interp(&interp_ex,
@@ -673,7 +705,7 @@ do_load_elf_binary(struct linux_binprm *
        bprm->inode->i_count++;
 #endif
 #ifdef LOW_ELF_STACK
-       current->start_stack = bprm->p = elf_stack - 4;
+       current->start_stack = bprm->p = elf_stack;
 #endif
        current->suid = current->euid = current->fsuid = bprm->e_uid;
        current->sgid = current->egid = current->fsgid = bprm->e_gid;

Reply via email to