[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: libc6 select problem SOLVED



Johnie Ingram wrote:
> 
> "Juan" == Juan Cespedes <cespedes@debian.org> 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.
 delaunay@lix.polytechnique.fr | 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 to: