Subject: COMPAT_LINUX: a problem with dup2()
To: None <tech-kern@netbsd.org>
From: Emmanuel Dreyfus <p99dreyf@criens.u-psud.fr>
List: tech-kern
Date: 12/31/2000 16:31:05
Happy new year everybody

I progressed in porting COMPAT_LINUX to powerpc. I'm now able to run on
NetBSD/macppc a hello world programm compiled on a LinuxPPC box.

Shared library do not work yet. I tried a test program to see if the
problem could comme from mmap():

#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

int main (int argc, char** argv) {
  int fd;
  char* ptr;
  
  fd=open("/etc/passwd",O_RDONLY,0);
  if (fd<0) {printf("open failed\n"); exit(-1);}

  (void*)ptr=mmap(NULL,512,PROT_READ,MAP_PRIVATE|MAP_FILE,fd,0);
  if (ptr==NULL) {perror("mmap failed"); exit(-1);}

  printf("%c-%c-%c-%c\n",ptr[0],ptr[1],ptr[2],ptr[3]);
  
  return 0;
}

This is statically linked, my goal is just to test mmap(). This program
crash on NetBSD, here is the kernel trace:

   325 ktrace   EMUL  "netbsd"
   325 ktrace   RET   ktrace 0
   325 ktrace   CALL  execve(0x7fffeac3,0x7fffea18,0x7fffea20)
   325 ktrace   NAMI  "./mmap"
   325 mmap     EMUL  "netbsd"
   325 mmap     RET   execve JUSTRETURN
   325 mmap     CALL  mkdir(0,0x7fffea14)
   325 mmap     RET   mkdir -1 errno 14 Bad address
   325 mmap     CALL  __getlogin(0,0)
   325 mmap     RET   __getlogin 0
   325 mmap     CALL  getuid
   325 mmap     RET   getuid 500/0x1f4
   325 mmap     CALL  open(0x1830b48,0,0)
   325 mmap     NAMI  "/etc/passwd"
   325 mmap     RET   open 3
   325 mmap     CALL  dup2(0,0x200)
   325 mmap     RET   dup2 -1 errno 9 Bad file descriptor
   325 mmap     PSIG  SIGSEGV SIG_DFL
   325 mmap     NAMI  "mmap.core"

Two questions: 
1) does anyone has an idea of why I have EMUL "netbsd" here whereas that
programm was compiled on a LinuxPPC box? This happens with statically
linked programs. When I run such an executable, I get a kernel debug
message "linux_gcc_sig: sig=", so I'm sure there is some Linux thing in
it. Dynamically linked programs have appropriate EMUL "linux" (and do
not work yet). I wonder if NetBSD does'nt think this is a real NetBSD
executable, and get it running by chance, because the syscalls I use
have same syscall number and arguments on NetBSD and Linux. If this is
the problem, what could make NetBSD recognise Linux binary when they are
dynamically linked and not when they are statically linked?

2) Here the problem is not mmap(), it's dup2(), that fail with the new
fd 0x200. I tried to compile and run this program on NetBSD (so there is
absolutely no linux emulation stuff here)
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

int main (int argc, char** argv) {
  int fd,fd2;
  
  fd=open("/etc/passwd",O_RDONLY,0);
  if (fd<0) {printf("open failed\n"); exit(-1);}

  fd2=dup2(fd,0x200);
  printf("fd2=%d\n",fd2);
  if (fd2<0) {perror ("dup2 failed"); exit (-1);}

  return 0;
}

It seems 0x200 is too much for dup2(). Fine, I can understand there is a
maximum for file descriptors, but Linux seems confortable with this
value. We need a workaround for this, since Linux can call dup2() with
values NetBSD does not accept. I see no Linux to NetBSD file descriptor
mapping in existing Linux eumlation code. Therefore, I assume that this
is specific to powerpc and that it will require some extra work, or that
I missed something. Did I miss something?

-- 
Emmanuel Dreyfus
p99dreyf@criens.u-psud.fr