Subject: Re: Linux emulation problems
To: Andreas Gustafsson <gson@araneus.fi>
From: Frank van der Linden <frank@fwi.uva.nl>
List: netbsd-help
Date: 10/20/1996 15:04:48
Quoting Andreas Gustafsson,

> I'm having trouble getting Linux ELF binaries to run under the
> NetBSD/i386 1.2 Linux emulation.  Linux a.out binaries work fine, 
> but execing ELF binaries fails.
[...]
> What is ld-linux.so.1?  It is not mentioned in the compat_linux(8) man
> page.  I tried installing the file /lib/ld-linux.so.1 from the Linux
> system under /emul/linux/lib, but still no luck:

ld-linux.so.1 is the dynamic loader for ELF binaries under Linux. The
ENOEXEC was caused by the exec code not finding it.

>    628 ktrace   CALL  execve(0xf7bfd8f7,0xf7bfd88c,0xf7bfd894)
>    628 ktrace   NAMI  "/emul/linux/bin/ls.elf"
>    628 ktrace   NAMI  "/emul/linux/lib/ld-linux.so.1"
>    628 ktrace   NAMI  "/emul/linux"
>    628 ktrace   NAMI  "/emul/linux/lib/ld-linux.so.1"
>    628 ktrace   RET   execve -1 errno 12 Cannot allocate memory

This looks like a problem that was fixed by cgd and Bob Baron in -current
the other day. The problem is that some (newer) Linux ELF binaries apparently
have just 1 loadable section, which contains both data and text. This confuses
the ELF exec code.

Try the following patch to your 1.2 tree, recompile the kernel and tell
me if it works. If it does, this should be in an official patch to 1.2.

- Frank


*** exec_elf.c.orig	Sat Feb 10 13:32:13 1996
--- exec_elf.c	Sun Oct 20 13:55:36 1996
***************
*** 405,412 ****
  				    (caddr_t) ph, phsize)) != 0)
  		goto bad;
  
! 	epp->ep_tsize = ELF32_NO_ADDR;
! 	epp->ep_dsize = ELF32_NO_ADDR;
  
  	interp[0] = '\0';
  
--- 405,412 ----
  				    (caddr_t) ph, phsize)) != 0)
  		goto bad;
  
! 	epp->ep_taddr = epp->ep_tsize = ELF32_NO_ADDR;
! 	epp->ep_daddr = epp->ep_dsize = ELF32_NO_ADDR;
  
  	interp[0] = '\0';
  
***************
*** 467,472 ****
--- 467,476 ----
  			if (eh->e_entry >= addr && eh->e_entry < (addr + size)){
  				epp->ep_taddr = addr;
  				epp->ep_tsize = size;
+ 				if (epp->ep_daddr == ELF32_NO_ADDR) {
+ 					epp->ep_daddr = addr;
+ 					epp->ep_dsize = size;
+ 				}
  			} else {
  				epp->ep_daddr = addr;
  				epp->ep_dsize = size;