home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / sim / ppc / emul_netbsd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-08  |  32.9 KB  |  1,361 lines

  1. /*  This file is part of the program psim.
  2.  
  3.     Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19.     */
  20.  
  21.  
  22. #ifndef _EMUL_NETBSD_C_
  23. #define _EMUL_NETBSD_C_
  24.  
  25.  
  26. /* Note: this module is called via a table.  There is no benefit in
  27.    making it inline */
  28.  
  29. #include "emul_generic.h"
  30. #include "emul_netbsd.h"
  31.  
  32. #ifdef HAVE_STRING_H
  33. #include <string.h>
  34. #else
  35. #ifdef HAVE_STRINGS_H
  36. #include <strings.h>
  37. #endif
  38. #endif
  39.  
  40. #include <sys/types.h>
  41. #include <sys/stat.h>
  42. #include <stdio.h>
  43. #include <signal.h>
  44. #include <fcntl.h>
  45. #include <sys/errno.h>
  46. #include <sys/param.h>
  47. #include <sys/time.h>
  48.  
  49. #ifdef HAVE_GETRUSAGE
  50. #ifndef HAVE_SYS_RESOURCE_H
  51. #undef HAVE_GETRUSAGE
  52. #endif
  53. #endif
  54.  
  55. #ifdef HAVE_GETRUSAGE
  56. #include <sys/resource.h>
  57. int getrusage();
  58. #endif
  59.  
  60. #include <sys/ioctl.h>
  61.  
  62. #if HAVE_SYS_MOUNT_H
  63. #include <sys/mount.h>
  64. #endif
  65.  
  66. #if HAVE_DIRENT_H
  67. # include <dirent.h>
  68. # define NAMLEN(dirent) strlen((dirent)->d_name)
  69. #else
  70. # define dirent direct
  71. # define NAMLEN(dirent) (dirent)->d_namlen
  72. # if HAVE_SYS_NDIR_H
  73. #  include <sys/ndir.h>
  74. # endif
  75. # if HAVE_SYS_DIR_H
  76. #  include <sys/dir.h>
  77. # endif
  78. # if HAVE_NDIR_H
  79. #  include <ndir.h>
  80. # endif
  81. #endif
  82.  
  83. #ifdef HAVE_UNISTD_H
  84. #include <unistd.h>
  85. #endif
  86.  
  87. #ifdef HAVE_STDLIB_H
  88. #include <stdlib.h>
  89. #endif
  90.  
  91. #define WITH_NetBSD_HOST (NetBSD >= 199306)
  92. #if WITH_NetBSD_HOST /* here NetBSD as that is what we're emulating */
  93. #include <sys/syscall.h> /* FIXME - should not be including this one */
  94. #include <sys/sysctl.h>
  95. extern int getdirentries(int fd, char *buf, int nbytes, long *basep);
  96. #endif
  97.  
  98. #if (BSD < 199306) /* here BSD as just a bug */
  99. extern int errno;
  100. #endif
  101.  
  102. #ifndef STATIC_INLINE_EMUL_NETBSD
  103. #define STATIC_INLINE_EMUL_NETBSD STATIC_INLINE
  104. #endif
  105.  
  106.  
  107. #if WITH_NetBSD_HOST
  108. #define SYS(X) ASSERT(call == (SYS_##X))
  109. #else
  110. #define SYS(X)
  111. #endif
  112.  
  113. #if WITH_NetBSD_HOST && (PATH_MAX != 1024)
  114. #error "PATH_MAX not 1024"
  115. #elif !defined(PATH_MAX)
  116. #define PATH_MAX 1024
  117. #endif
  118.  
  119.  
  120. /* NetBSD's idea of what is needed to implement emulations */
  121.  
  122. struct _os_emul_data {
  123.   device *vm;
  124.   emul_syscall *syscalls;
  125. };
  126.  
  127.  
  128.  
  129. STATIC_INLINE_EMUL_NETBSD void
  130. write_stat(unsigned_word addr,
  131.        struct stat buf,
  132.        cpu *processor,
  133.        unsigned_word cia)
  134. {
  135.   H2T(buf.st_dev);
  136.   H2T(buf.st_ino);
  137.   H2T(buf.st_mode);
  138.   H2T(buf.st_nlink);
  139.   H2T(buf.st_uid);
  140.   H2T(buf.st_gid);
  141.   H2T(buf.st_rdev);
  142.   H2T(buf.st_size);
  143.   H2T(buf.st_atime);
  144.   /* H2T(buf.st_spare1); */
  145.   H2T(buf.st_mtime);
  146.   /* H2T(buf.st_spare2); */
  147.   H2T(buf.st_ctime);
  148.   /* H2T(buf.st_spare3); */
  149.   H2T(buf.st_blksize);
  150.   H2T(buf.st_blocks);
  151. #if WITH_NetBSD_HOST
  152.   H2T(buf.st_flags);
  153.   H2T(buf.st_gen);
  154. #endif
  155.   emul_write_buffer(&buf, addr, sizeof(buf), processor, cia);
  156. }
  157.  
  158.   
  159. #if NetBSD
  160. STATIC_INLINE_EMUL_NETBSD void
  161. write_statfs(unsigned_word addr,
  162.          struct statfs buf,
  163.          cpu *processor,
  164.          unsigned_word cia)
  165. {
  166.   H2T(buf.f_type);
  167.   H2T(buf.f_flags);
  168.   H2T(buf.f_bsize);
  169.   H2T(buf.f_iosize);
  170.   H2T(buf.f_blocks);
  171.   H2T(buf.f_bfree);
  172.   H2T(buf.f_bavail);
  173.   H2T(buf.f_files);
  174.   H2T(buf.f_ffree);
  175.   H2T(buf.f_fsid.val[0]);
  176.   H2T(buf.f_fsid.val[1]);
  177.   H2T(buf.f_owner);
  178.   /* f_spare[4]; */
  179.   /* f_fstypename[MFSNAMELEN]; */
  180.   /* f_mntonname[MNAMELEN]; */
  181.   /* f_mntfromname[MNAMELEN]; */
  182.   emul_write_buffer(&buf, addr, sizeof(buf), processor, cia);
  183. }
  184. #endif
  185.  
  186.   
  187. STATIC_INLINE_EMUL_NETBSD void
  188. write_timeval(unsigned_word addr,
  189.           struct timeval t,
  190.           cpu *processor,
  191.           unsigned_word cia)
  192. {
  193.   H2T(t.tv_sec);
  194.   H2T(t.tv_usec);
  195.   emul_write_buffer(&t, addr, sizeof(t), processor, cia);
  196. }
  197.  
  198.   
  199. STATIC_INLINE_EMUL_NETBSD void
  200. write_timezone(unsigned_word addr,
  201.            struct timezone tz,
  202.            cpu *processor,
  203.            unsigned_word cia)
  204. {
  205.   H2T(tz.tz_minuteswest);
  206.   H2T(tz.tz_dsttime);
  207.   emul_write_buffer(&tz, addr, sizeof(tz), processor, cia);
  208. }
  209.  
  210.   
  211. #if WITH_NetBSD_HOST
  212. STATIC_INLINE_EMUL_NETBSD void
  213. write_direntries(unsigned_word addr,
  214.          char *buf,
  215.          int nbytes,
  216.          cpu *processor,
  217.          unsigned_word cia)
  218. {
  219.   while (nbytes > 0) {
  220.     struct dirent *out;
  221.     struct dirent *in = (struct dirent*)buf;
  222.     ASSERT(in->d_reclen <= nbytes);
  223.     out = (struct dirent*)zalloc(in->d_reclen);
  224.     memcpy(out/*dest*/, in/*src*/, in->d_reclen);
  225.     H2T(out->d_fileno);
  226.     H2T(out->d_reclen);
  227.     H2T(out->d_type);
  228.     H2T(out->d_namlen);
  229.     emul_write_buffer(out, addr, in->d_reclen, processor, cia);
  230.     nbytes -= in->d_reclen;
  231.     addr += in->d_reclen;
  232.     buf += in->d_reclen;
  233.     zfree(out);
  234.   }
  235. }
  236. #endif
  237.  
  238.  
  239. #ifdef HAVE_GETRUSAGE
  240. STATIC_INLINE_EMUL_NETBSD void
  241. write_rusage(unsigned_word addr,
  242.          struct rusage rusage,
  243.          cpu *processor,
  244.          unsigned_word cia)
  245. {
  246.   H2T(rusage.ru_utime.tv_sec); /* user time used */
  247.   H2T(rusage.ru_utime.tv_usec);
  248.   H2T(rusage.ru_stime.tv_sec); /* system time used */
  249.   H2T(rusage.ru_stime.tv_usec);
  250.   H2T(rusage.ru_maxrss);          /* integral max resident set size */
  251.   H2T(rusage.ru_ixrss);           /* integral shared text memory size */
  252.   H2T(rusage.ru_idrss);           /* integral unshared data size */
  253.   H2T(rusage.ru_isrss);           /* integral unshared stack size */
  254.   H2T(rusage.ru_minflt);          /* page reclaims */
  255.   H2T(rusage.ru_majflt);          /* page faults */
  256.   H2T(rusage.ru_nswap);           /* swaps */
  257.   H2T(rusage.ru_inblock);         /* block input operations */
  258.   H2T(rusage.ru_oublock);         /* block output operations */
  259.   H2T(rusage.ru_msgsnd);          /* messages sent */
  260.   H2T(rusage.ru_msgrcv);          /* messages received */
  261.   H2T(rusage.ru_nsignals);        /* signals received */
  262.   H2T(rusage.ru_nvcsw);           /* voluntary context switches */
  263.   H2T(rusage.ru_nivcsw);          /* involuntary context switches */
  264.   emul_write_buffer(&rusage, addr, sizeof(rusage), processor, cia);
  265. }
  266. #endif
  267.   
  268. static void
  269. do_exit(os_emul_data *emul,
  270.     unsigned call,
  271.     const int arg0,
  272.     cpu *processor,
  273.     unsigned_word cia)
  274. {
  275.   int status = (int)cpu_registers(processor)->gpr[arg0];
  276.   SYS(exit);
  277.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  278.     printf_filtered ("%d)\n", status);
  279.  
  280.   cpu_halt(processor, cia, was_exited, status);
  281. }
  282.  
  283.  
  284. static void
  285. do_read(os_emul_data *emul,
  286.     unsigned call,
  287.     const int arg0,
  288.     cpu *processor,
  289.     unsigned_word cia)
  290. {
  291.   void *scratch_buffer;
  292.   int d = (int)cpu_registers(processor)->gpr[arg0];
  293.   unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
  294.   int nbytes = cpu_registers(processor)->gpr[arg0+2];
  295.   int status;
  296.   SYS(read);
  297.   
  298.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  299.     printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes);
  300.  
  301.   /* get a tempoary bufer */
  302.   scratch_buffer = zalloc(nbytes);
  303.   
  304.   /* check if buffer exists by reading it */
  305.   emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia);
  306.   
  307.   /* read */
  308. #if 0
  309.   if (d == 0) {
  310.     status = fread (scratch_buffer, 1, nbytes, stdin);
  311.     if (status == 0 && ferror (stdin))
  312.       status = -1;
  313.   }
  314. #endif
  315.   status = read (d, scratch_buffer, nbytes);
  316.   
  317.   if (status == -1) {
  318.     cpu_registers(processor)->gpr[0] = errno;
  319.   } else {
  320.     cpu_registers(processor)->gpr[3] = status;
  321.     
  322.     if (status > 0)
  323.       emul_write_buffer(scratch_buffer, buf, status, processor, cia);
  324.   }
  325.   
  326.   zfree(scratch_buffer);
  327. }
  328.  
  329.  
  330. static void
  331. do_write(os_emul_data *emul,
  332.      unsigned call,
  333.      const int arg0,
  334.      cpu *processor,
  335.      unsigned_word cia)
  336. {
  337.   void *scratch_buffer = NULL;
  338.   int nr_moved;
  339.   int d = (int)cpu_registers(processor)->gpr[arg0];
  340.   unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
  341.   int nbytes = cpu_registers(processor)->gpr[arg0+2];
  342.   int status;
  343.   SYS(write);
  344.   
  345.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  346.     printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes);
  347.  
  348.   /* get a tempoary bufer */
  349.   scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */
  350.   
  351.   /* copy in */
  352.   nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
  353.                      scratch_buffer,
  354.                      buf,
  355.                      nbytes);
  356.   if (nr_moved != nbytes) {
  357.     /* FIXME - should handle better */
  358.     error("system_call()write copy failed (nr_moved=%d != nbytes=%d)\n",
  359.       nr_moved, nbytes);
  360.   }
  361.   
  362.   /* write */
  363.   status = write(d, scratch_buffer, nbytes);
  364.   emul_write_status(processor, status, errno);
  365.   zfree(scratch_buffer);
  366.  
  367.   flush_stdoutput();
  368. }
  369.  
  370.  
  371. static void
  372. do_open(os_emul_data *emul,
  373.     unsigned call,
  374.     const int arg0,
  375.     cpu *processor,
  376.     unsigned_word cia)
  377. {
  378.   unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
  379.   char path_buf[PATH_MAX];
  380.   char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
  381.   int flags = (int)cpu_registers(processor)->gpr[arg0+1];
  382.   int mode = (int)cpu_registers(processor)->gpr[arg0+2];
  383.  
  384.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  385.     printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode);
  386.  
  387.   SYS(open);
  388.   emul_write_status(processor, open(path, flags, mode), errno);
  389. }
  390.  
  391.  
  392. static void
  393. do_close(os_emul_data *emul,
  394.      unsigned call,
  395.      const int arg0,
  396.      cpu *processor,
  397.      unsigned_word cia)
  398. {
  399.   int d = (int)cpu_registers(processor)->gpr[arg0];
  400.  
  401.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  402.     printf_filtered ("%d", d);
  403.  
  404.   SYS(close);
  405.   emul_write_status(processor, close(d), errno);
  406. }
  407.  
  408.  
  409. static void
  410. do_break(os_emul_data *emul,
  411.      unsigned call,
  412.      const int arg0,
  413.      cpu *processor,
  414.      unsigned_word cia)
  415. {
  416.   /* just pass this onto the `vm' device */
  417.   psim *system = cpu_system(processor);
  418.  
  419.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  420.     printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]);
  421.  
  422.   SYS(break);
  423.   device_ioctl(emul->vm,
  424.            system,
  425.            processor,
  426.            cia,
  427.            0, /*ioctl*/
  428.            NULL); /*ioctl-data*/
  429. }
  430.  
  431.  
  432. static void
  433. do_getpid(os_emul_data *emul,
  434.       unsigned call,
  435.       const int arg0,
  436.       cpu *processor,
  437.       unsigned_word cia)
  438. {
  439.   SYS(getpid);
  440.   cpu_registers(processor)->gpr[3] = (int)getpid();
  441. }
  442.  
  443.  
  444. static void
  445. do_getuid(os_emul_data *emul,
  446.       unsigned call,
  447.       const int arg0,
  448.       cpu *processor,
  449.       unsigned_word cia)
  450. {
  451.   SYS(getuid);
  452.   cpu_registers(processor)->gpr[3] = (int)getuid();
  453. }
  454.  
  455.  
  456. static void
  457. do_geteuid(os_emul_data *emul,
  458.        unsigned call,
  459.        const int arg0,
  460.        cpu *processor,
  461.        unsigned_word cia)
  462. {
  463.   SYS(geteuid);
  464.   cpu_registers(processor)->gpr[3] = (int)geteuid();
  465. }
  466.  
  467.  
  468. static void
  469. do_kill(os_emul_data *emul,
  470.     unsigned call,
  471.     const int arg0,
  472.     cpu *processor,
  473.     unsigned_word cia)
  474. {
  475.   pid_t pid = cpu_registers(processor)->gpr[arg0];
  476.   int sig = cpu_registers(processor)->gpr[arg0+1];
  477.  
  478.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  479.     printf_filtered ("%d, %d", (int)pid, sig);
  480.  
  481.   SYS(kill);
  482.   printf_filtered("SYS_kill at 0x%lx - more to this than just being killed\n",
  483.           (long)cia);
  484.   cpu_halt(processor, cia, was_signalled, sig);
  485. }
  486.  
  487.  
  488. static void
  489. do_dup(os_emul_data *emul,
  490.        unsigned call,
  491.        const int arg0,
  492.        cpu *processor,
  493.        unsigned_word cia)
  494. {
  495.   int oldd = cpu_registers(processor)->gpr[arg0];
  496.   int status = dup(oldd);
  497.  
  498.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  499.     printf_filtered ("%d", oldd);
  500.  
  501.   SYS(dup);
  502.   emul_write_status(processor, status, errno);
  503. }
  504.  
  505.  
  506. static void
  507. do_getegid(os_emul_data *emul,
  508.        unsigned call,
  509.        const int arg0,
  510.        cpu *processor,
  511.        unsigned_word cia)
  512. {
  513.   SYS(getegid);
  514.   cpu_registers(processor)->gpr[3] = (int)getegid();
  515. }
  516.  
  517.  
  518. static void
  519. do_getgid(os_emul_data *emul,
  520.       unsigned call,
  521.       const int arg0,
  522.       cpu *processor,
  523.       unsigned_word cia)
  524. {
  525.   SYS(getgid);
  526.   cpu_registers(processor)->gpr[3] = (int)getgid();
  527. }
  528.  
  529.  
  530. static void
  531. do_sigprocmask(os_emul_data *emul,
  532.            unsigned call,
  533.            const int arg0,
  534.            cpu *processor,
  535.            unsigned_word cia)
  536. {
  537.   natural_word how = cpu_registers(processor)->gpr[arg0];
  538.   unsigned_word set = cpu_registers(processor)->gpr[arg0+1];
  539.   unsigned_word oset = cpu_registers(processor)->gpr[arg0+2];
  540.   SYS(sigprocmask);
  541.  
  542.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  543.     printf_filtered ("%ld, 0x%ld, 0x%ld", (long)how, (long)set, (long)oset);
  544.  
  545.   cpu_registers(processor)->gpr[3] = 0;
  546.   cpu_registers(processor)->gpr[4] = set;
  547. }
  548.  
  549.  
  550. static void
  551. do_ioctl(os_emul_data *emul,
  552.      unsigned call,
  553.      const int arg0,
  554.      cpu *processor,
  555.      unsigned_word cia)
  556. {
  557.   int d = cpu_registers(processor)->gpr[arg0];
  558.   unsigned request = cpu_registers(processor)->gpr[arg0+1];
  559.   unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2];
  560.  
  561. #if !WITH_NetBSD_HOST
  562.   cpu_registers(processor)->gpr[arg0] = 0; /* just succeed */
  563. #else
  564.   unsigned dir = request & IOC_DIRMASK;
  565.   int status;
  566.   SYS(ioctl);
  567.   /* what we haven't done */
  568.   if (dir & IOC_IN /* write into the io device */
  569.       || dir & IOC_OUT
  570.       || !(dir & IOC_VOID))
  571.     error("do_ioctl() read or write of parameter not implemented\n");
  572.   status = ioctl(d, request, NULL);
  573.   emul_write_status(processor, status, errno);
  574. #endif
  575.  
  576.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  577.     printf_filtered ("%d, 0x%x, 0x%lx", d, request, (long)argp_addr);
  578. }
  579.  
  580.  
  581. static void
  582. do_umask(os_emul_data *emul,
  583.      unsigned call,
  584.      const int arg0,
  585.      cpu *processor,
  586.      unsigned_word cia)
  587. {
  588.   int mask = cpu_registers(processor)->gpr[arg0];
  589.  
  590.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  591.     printf_filtered ("0%o", mask);
  592.  
  593.   SYS(umask);
  594.   cpu_registers(processor)->gpr[3] = umask(mask);
  595. }
  596.  
  597.  
  598. static void
  599. do_dup2(os_emul_data *emul,
  600.     unsigned call,
  601.     const int arg0,
  602.     cpu *processor,
  603.     unsigned_word cia)
  604. {
  605.   int oldd = cpu_registers(processor)->gpr[arg0];
  606.   int newd = cpu_registers(processor)->gpr[arg0+1];
  607.   int status = dup2(oldd, newd);
  608.  
  609.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  610.     printf_filtered ("%d, %d", oldd, newd);
  611.  
  612.   SYS(dup2);
  613.   emul_write_status(processor, status, errno);
  614. }
  615.  
  616.  
  617. static void
  618. do_fcntl(os_emul_data *emul,
  619.      unsigned call,
  620.      const int arg0,
  621.      cpu *processor,
  622.      unsigned_word cia)
  623. {
  624.   int fd = cpu_registers(processor)->gpr[arg0];
  625.   int cmd = cpu_registers(processor)->gpr[arg0+1];
  626.   int arg = cpu_registers(processor)->gpr[arg0+2];
  627.   int status;
  628.  
  629.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  630.     printf_filtered ("%d, %d, %d", fd, cmd, arg);
  631.  
  632.   SYS(fcntl);
  633.   status = fcntl(fd, cmd, arg);
  634.   emul_write_status(processor, status, errno);
  635. }
  636.  
  637.  
  638. static void
  639. do_gettimeofday(os_emul_data *emul,
  640.         unsigned call,
  641.         const int arg0,
  642.         cpu *processor,
  643.         unsigned_word cia)
  644. {
  645.   unsigned_word t_addr = cpu_registers(processor)->gpr[arg0];
  646.   unsigned_word tz_addr = cpu_registers(processor)->gpr[arg0+1];
  647.   struct timeval t;
  648.   struct timezone tz;
  649.   int status = gettimeofday((t_addr != 0 ? &t : NULL),
  650.                 (tz_addr != 0 ? &tz : NULL));
  651.  
  652.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  653.     printf_filtered ("0x%lx, 0x%lx", (long)t_addr, (long)tz_addr);
  654.  
  655.   SYS(gettimeofday);
  656.   emul_write_status(processor, status, errno);
  657.   if (status == 0) {
  658.     if (t_addr != 0)
  659.       write_timeval(t_addr, t, processor, cia);
  660.     if (tz_addr != 0)
  661.       write_timezone(tz_addr, tz, processor, cia);
  662.   }
  663. }
  664.  
  665.  
  666. #ifndef HAVE_GETRUSAGE
  667. #define do_getrusage 0
  668. #else
  669. static void
  670. do_getrusage(os_emul_data *emul,
  671.          unsigned call,
  672.          const int arg0,
  673.          cpu *processor,
  674.          unsigned_word cia)
  675. {
  676.   int who = cpu_registers(processor)->gpr[arg0];
  677.   unsigned_word rusage_addr = cpu_registers(processor)->gpr[arg0+1];
  678.   struct rusage rusage;
  679.   int status = getrusage(who, (rusage_addr != 0 ? &rusage : NULL));
  680.  
  681.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  682.     printf_filtered ("%d, 0x%lx", who, (long)rusage_addr);
  683.  
  684.   SYS(getrusage);
  685.   emul_write_status(processor, status, errno);
  686.   if (status == 0) {
  687.     if (rusage_addr != 0)
  688.       write_rusage(rusage_addr, rusage, processor, cia);
  689.   }
  690. }
  691. #endif
  692.  
  693.  
  694. #if !WITH_NetBSD_HOST
  695. #define do_fstatfs 0
  696. #else
  697. static void
  698. do_fstatfs(os_emul_data *emul,
  699.        unsigned call,
  700.        const int arg0,
  701.        cpu *processor,
  702.        unsigned_word cia)
  703. {
  704.   int fd = cpu_registers(processor)->gpr[arg0];
  705.   unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1];
  706.   struct statfs buf;
  707.   int status;
  708.  
  709.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  710.     printf_filtered ("%d, 0x%lx", fd, (long)buf_addr);
  711.  
  712.   SYS(fstatfs);
  713.   status = fstatfs(fd, (buf_addr == 0 ? NULL : &buf));
  714.   emul_write_status(processor, status, errno);
  715.   if (status == 0) {
  716.     if (buf_addr != 0)
  717.       write_statfs(buf_addr, buf, processor, cia);
  718.   }
  719. }
  720. #endif
  721.  
  722.  
  723. static void
  724. do_stat(os_emul_data *emul,
  725.     unsigned call,
  726.     const int arg0,
  727.     cpu *processor,
  728.     unsigned_word cia)
  729. {
  730.   char path_buf[PATH_MAX];
  731.   unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
  732.   unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
  733.   char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
  734.   struct stat buf;
  735.   int status;
  736.   SYS(stat);
  737.   status = stat(path, &buf);
  738.   emul_write_status(processor, status, errno);
  739.   if (status == 0)
  740.     write_stat(stat_buf_addr, buf, processor, cia);
  741. }
  742.  
  743.  
  744. static void
  745. do_fstat(os_emul_data *emul,
  746.      unsigned call,
  747.      const int arg0,
  748.      cpu *processor,
  749.      unsigned_word cia)
  750. {
  751.   int fd = cpu_registers(processor)->gpr[arg0];
  752.   unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
  753.   struct stat buf;
  754.   SYS(fstat);
  755.   emul_write_status(processor, fstat(fd, &buf), errno);
  756.   write_stat(stat_buf_addr, buf, processor, cia);
  757. }
  758.  
  759.  
  760. static void
  761. do_lstat(os_emul_data *emul,
  762.      unsigned call,
  763.      const int arg0,
  764.      cpu *processor,
  765.      unsigned_word cia)
  766. {
  767.   char path_buf[PATH_MAX];
  768.   unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
  769.   char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
  770.   unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
  771.   struct stat buf;
  772.   SYS(lstat);
  773.   emul_write_status(processor, stat(path, &buf), errno);
  774.   write_stat(stat_buf_addr, buf, processor, cia);
  775. }
  776.  
  777.  
  778. #if !WITH_NetBSD_HOST
  779. #define do_getdirentries 0
  780. #else
  781. static void
  782. do_getdirentries(os_emul_data *emul,
  783.          unsigned call,
  784.          const int arg0,
  785.          cpu *processor,
  786.          unsigned_word cia)
  787. {
  788.   int fd = cpu_registers(processor)->gpr[arg0];
  789.   unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1];
  790.   char *buf;
  791.   int nbytes = cpu_registers(processor)->gpr[arg0+2];
  792.   unsigned_word basep_addr = cpu_registers(processor)->gpr[arg0+3];
  793.   long basep;
  794.   int status;
  795.   SYS(getdirentries);
  796.   if (buf_addr != 0 && nbytes >= 0)
  797.     buf = zalloc(nbytes);
  798.   else
  799.     buf = NULL;
  800.   status = getdirentries(fd,
  801.              (buf_addr == 0 ? NULL : buf),
  802.              nbytes,
  803.              (basep_addr == 0 ? NULL : &basep));
  804.   emul_write_status(processor, status, errno);
  805.   if (basep_addr != 0)
  806.     emul_write_word(basep_addr, basep, processor, cia);
  807.   if (status > 0)
  808.     write_direntries(buf_addr, buf, status, processor, cia);
  809.   if (buf != NULL)
  810.     zfree(buf);
  811. }
  812. #endif
  813.  
  814.  
  815. static void
  816. do___syscall(os_emul_data *emul,
  817.          unsigned call,
  818.          const int arg0,
  819.          cpu *processor,
  820.          unsigned_word cia)
  821. {
  822.   SYS(__syscall);
  823.   emul_do_system_call(emul,
  824.               emul->syscalls,
  825.               cpu_registers(processor)->gpr[arg0],
  826.               arg0 + 1,
  827.               processor,
  828.               cia);
  829. }
  830.  
  831.  
  832. static void
  833. do_lseek(os_emul_data *emul,
  834.      unsigned call,
  835.      const int arg0,
  836.      cpu *processor,
  837.      unsigned_word cia)
  838. {
  839.   int fildes = cpu_registers(processor)->gpr[arg0];
  840.   off_t offset = emul_read_gpr64(processor, arg0+2);
  841.   int whence = cpu_registers(processor)->gpr[arg0+4];
  842.   off_t status;
  843.   SYS(lseek);
  844.   status = lseek(fildes, offset, whence);
  845.   if (status == -1)
  846.     emul_write_status(processor, -1, errno);
  847.   else {
  848.     emul_write_gpr64(processor, 3, status);
  849.   }
  850. }
  851.  
  852.  
  853. static void
  854. do___sysctl(os_emul_data *emul,
  855.         unsigned call,
  856.         const int arg0,
  857.         cpu *processor,
  858.         unsigned_word cia)
  859. {
  860.   /* call the arguments by their real name */
  861.   unsigned_word name = cpu_registers(processor)->gpr[arg0];
  862.   natural_word namelen = cpu_registers(processor)->gpr[arg0+1];
  863.   unsigned_word oldp = cpu_registers(processor)->gpr[arg0+2];
  864.   unsigned_word oldlenp = cpu_registers(processor)->gpr[arg0+3];
  865.   natural_word oldlen;
  866.   natural_word mib;
  867.   natural_word int_val;
  868.   SYS(__sysctl);
  869.  
  870.   /* pluck out the management information base id */
  871.   if (namelen < 1)
  872.     error("system_call()SYS___sysctl bad name[0]\n");
  873.   mib = vm_data_map_read_word(cpu_data_map(processor),
  874.                   name,
  875.                   processor,
  876.                   cia);
  877.   name += sizeof(mib);
  878.   
  879.   /* see what to do with it ... */
  880.   switch ((int)mib) {
  881.   case 6/*CTL_HW*/:
  882. #if WITH_NetBSD_HOST && (CTL_HW != 6)
  883. #  error "CTL_HW"
  884. #endif
  885.     if (namelen < 2)
  886.       error("system_call()SYS___sysctl - CTL_HW - bad name[1]\n");
  887.     mib = vm_data_map_read_word(cpu_data_map(processor),
  888.                 name,
  889.                 processor,
  890.                 cia);
  891.     name += sizeof(mib);
  892.     switch ((int)mib) {
  893.     case 7/*HW_PAGESIZE*/:
  894. #if WITH_NetBSD_HOST && (HW_PAGESIZE != 7)
  895. #  error "HW_PAGESIZE"
  896. #endif
  897.       oldlen = vm_data_map_read_word(cpu_data_map(processor),
  898.                      oldlenp,
  899.                      processor,
  900.                      cia);
  901.       if (sizeof(natural_word) > oldlen)
  902.     error("system_call()sysctl - CTL_HW.HW_PAGESIZE - to small\n");
  903.       int_val = 8192;
  904.       oldlen = sizeof(int_val);
  905.       emul_write_word(oldp, int_val, processor, cia);
  906.       emul_write_word(oldlenp, oldlen, processor, cia);
  907.       break;
  908.     default:
  909.       error("sysctl() CTL_HW.%d unknown\n", mib);
  910.       break;
  911.     }
  912.     break;
  913.   default:
  914.     error("sysctl() name[0]=%d unknown\n", (int)mib);
  915.     break;
  916.   }
  917.   cpu_registers(processor)->gpr[3] = 0;
  918. }
  919.  
  920.  
  921.  
  922. static emul_syscall_descriptor netbsd_descriptors[] = {
  923.   /* 0 */ { 0, "syscall" },
  924.   /* 1 */ { do_exit, "exit" },
  925.   /* 2 */ { 0, "fork" },      
  926.   /* 3 */ { do_read, "read" },
  927.   /* 4 */ { do_write, "write" },
  928.   /* 5 */ { do_open, "open" },
  929.   /* 6 */ { do_close, "close" },
  930.   /* 7 */ { 0, "wait4" },
  931.   { 0, }, /* 8 is old creat */
  932.   /* 9 */ { 0, "link" },
  933.   /* 10 */ { 0, "unlink" },
  934.   { 0, }, /* 11 is obsolete execv */
  935.   /* 12 */ { 0, "chdir" },
  936.   /* 13 */ { 0, "fchdir" },
  937.   /* 14 */ { 0, "mknod" },
  938.   /* 15 */ { 0, "chmod" },
  939.   /* 16 */ { 0, "chown" },
  940.   /* 17 */ { do_break, "break" },
  941.   /* 18 */ { 0, "getfsstat" },
  942.   { 0, }, /* 19 is old lseek */
  943.   /* 20 */ { do_getpid, "getpid" },
  944.   /* 21 */ { 0, "mount" },
  945.   /* 22 */ { 0, "unmount" },
  946.   /* 23 */ { 0, "setuid" },
  947.   /* 24 */ { do_getuid, "getuid" },
  948.   /* 25 */ { do_geteuid, "geteuid" },
  949.   /* 26 */ { 0, "ptrace" },
  950.   /* 27 */ { 0, "recvmsg" },
  951.   /* 28 */ { 0, "sendmsg" },
  952.   /* 29 */ { 0, "recvfrom" },
  953.   /* 30 */ { 0, "accept" },
  954.   /* 31 */ { 0, "getpeername" },
  955.   /* 32 */ { 0, "getsockname" },
  956.   /* 33 */ { 0, "access" },
  957.   /* 34 */ { 0, "chflags" },
  958.   /* 35 */ { 0, "fchflags" },
  959.   /* 36 */ { 0, "sync" },
  960.   /* 37 */ { do_kill, "kill" },
  961.   { 0, }, /* 38 is old stat */
  962.   /* 39 */ { 0, "getppid" },
  963.   { 0, }, /* 40 is old lstat */
  964.   /* 41 */ { do_dup, "dup" },
  965.   /* 42 */ { 0, "pipe" },
  966.   /* 43 */ { do_getegid, "getegid" },
  967.   /* 44 */ { 0, "profil" },
  968.   /* 45 */ { 0, "ktrace" },
  969.   /* 46 */ { 0, "sigaction" },
  970.   /* 47 */ { do_getgid, "getgid" },
  971.   /* 48 */ { do_sigprocmask, "sigprocmask" },
  972.   /* 49 */ { 0, "getlogin" },
  973.   /* 50 */ { 0, "setlogin" },
  974.   /* 51 */ { 0, "acct" },
  975.   /* 52 */ { 0, "sigpending" },
  976.   /* 53 */ { 0, "sigaltstack" },
  977.   /* 54 */ { do_ioctl, "ioctl" },
  978.   /* 55 */ { 0, "reboot" },
  979.   /* 56 */ { 0, "revoke" },
  980.   /* 57 */ { 0, "symlink" },
  981.   /* 58 */ { 0, "readlink" },
  982.   /* 59 */ { 0, "execve" },
  983.   /* 60 */ { do_umask, "umask" },
  984.   /* 61 */ { 0, "chroot" },
  985.   { 0, }, /* 62 is old fstat */
  986.   { 0, }, /* 63 is old getkerninfo */
  987.   { 0, }, /* 64 is old getpagesize */
  988.   /* 65 */ { 0, "msync" },
  989.   /* 66 */ { 0, "vfork" },
  990.   { 0, }, /* 67 is obsolete vread */
  991.   { 0, }, /* 68 is obsolete vwrite */
  992.   /* 69 */ { 0, "sbrk" },
  993.   /* 70 */ { 0, "sstk" },
  994.   { 0, }, /* 71 is old mmap */
  995.   /* 72 */ { 0, "vadvise" },
  996.   /* 73 */ { 0, "munmap" },
  997.   /* 74 */ { 0, "mprotect" },
  998.   /* 75 */ { 0, "madvise" },
  999.   { 0, }, /* 76 is obsolete vhangup */
  1000.   { 0, }, /* 77 is obsolete vlimit */
  1001.   /* 78 */ { 0, "mincore" },
  1002.   /* 79 */ { 0, "getgroups" },
  1003.   /* 80 */ { 0, "setgroups" },
  1004.   /* 81 */ { 0, "getpgrp" },
  1005.   /* 82 */ { 0, "setpgid" },
  1006.   /* 83 */ { 0, "setitimer" },
  1007.   { 0, }, /* 84 is old wait */
  1008.   /* 85 */ { 0, "swapon" },
  1009.   /* 86 */ { 0, "getitimer" },
  1010.   { 0, }, /* 87 is old gethostname */
  1011.   { 0, }, /* 88 is old sethostname */
  1012.   { 0, }, /* 89 is old getdtablesize */
  1013.   { do_dup2, "dup2" },
  1014.   { 0, }, /* 91 */
  1015.   /* 92 */ { do_fcntl, "fcntl" },
  1016.   /* 93 */ { 0, "select" },
  1017.   { 0, }, /* 94 */
  1018.   /* 95 */ { 0, "fsync" },
  1019.   /* 96 */ { 0, "setpriority" },
  1020.   /* 97 */ { 0, "socket" },
  1021.   /* 98 */ { 0, "connect" },
  1022.   { 0, }, /* 99 is old accept */
  1023.   /* 100 */ { 0, "getpriority" },
  1024.   { 0, }, /* 101 is old send */
  1025.   { 0, }, /* 102 is old recv */
  1026.   /* 103 */ { 0, "sigreturn" },
  1027.   /* 104 */ { 0, "bind" },
  1028.   /* 105 */ { 0, "setsockopt" },
  1029.   /* 106 */ { 0, "listen" },
  1030.   { 0, }, /* 107 is obsolete vtimes */
  1031.   { 0, }, /* 108 is old sigvec */
  1032.   { 0, }, /* 109 is old sigblock */
  1033.   { 0, }, /* 110 is old sigsetmask */
  1034.   /* 111 */ { 0, "sigsuspend" },
  1035.   { 0, }, /* 112 is old sigstack */
  1036.   { 0, }, /* 113 is old recvmsg */
  1037.   { 0, }, /* 114 is old sendmsg */
  1038.   /* - is obsolete vtrace */ { 0, "vtrace    115" },
  1039.   /* 116 */ { do_gettimeofday, "gettimeofday" },
  1040.   /* 117 */ { do_getrusage, "getrusage" },
  1041.   /* 118 */ { 0, "getsockopt" },
  1042.   /* 119 */ { 0, "resuba" },
  1043.   /* 120 */ { 0, "readv" },
  1044.   /* 121 */ { 0, "writev" },
  1045.   /* 122 */ { 0, "settimeofday" },
  1046.   /* 123 */ { 0, "fchown" },
  1047.   /* 124 */ { 0, "fchmod" },
  1048.   { 0, }, /* 125 is old recvfrom */
  1049.   { 0, }, /* 126 is old setreuid */
  1050.   { 0, }, /* 127 is old setregid */
  1051.   /* 128 */ { 0, "rename" },
  1052.   { 0, }, /* 129 is old truncate */
  1053.   { 0, }, /* 130 is old ftruncate */
  1054.   /* 131 */ { 0, "flock" },
  1055.   /* 132 */ { 0, "mkfifo" },
  1056.   /* 133 */ { 0, "sendto" },
  1057.   /* 134 */ { 0, "shutdown" },
  1058.   /* 135 */ { 0, "socketpair" },
  1059.   /* 136 */ { 0, "mkdir" },
  1060.   /* 137 */ { 0, "rmdir" },
  1061.   /* 138 */ { 0, "utimes" },
  1062.   { 0, }, /* 139 is obsolete 4.2 sigreturn */
  1063.   /* 140 */ { 0, "adjtime" },
  1064.   { 0, }, /* 141 is old getpeername */
  1065.   { 0, }, /* 142 is old gethostid */
  1066.   { 0, }, /* 143 is old sethostid */
  1067.   { 0, }, /* 144 is old getrlimit */
  1068.   { 0, }, /* 145 is old setrlimit */
  1069.   { 0, }, /* 146 is old killpg */
  1070.   /* 147 */ { 0, "setsid" },
  1071.   /* 148 */ { 0, "quotactl" },
  1072.   { 0, }, /* 149 is old quota */
  1073.   { 0, }, /* 150 is old getsockname */
  1074.   { 0, }, /* 151 */
  1075.   { 0, }, /* 152 */
  1076.   { 0, }, /* 153 */
  1077.   { 0, }, /* 154 */
  1078.   /* 155 */ { 0, "nfssvc" },
  1079.   { 0, }, /* 156 is old getdirentries */
  1080.   /* 157 */ { 0, "statfs" },
  1081.   /* 158 */ { do_fstatfs, "fstatfs" },
  1082.   { 0, }, /* 159 */
  1083.   { 0, }, /* 160 */
  1084.   /* 161 */ { 0, "getfh" },
  1085.   { 0, }, /* 162 is old getdomainname */
  1086.   { 0, }, /* 163 is old setdomainname */
  1087.   { 0, }, /* 164 is old uname */
  1088.   /* 165 */ { 0, "sysarch" },
  1089.   { 0, }, /* 166 */
  1090.   { 0, }, /* 167 */
  1091.   { 0, }, /* 168 */
  1092.   /* 169 */ { 0, "semsys" },
  1093.   /* 170 */ { 0, "msgsys" },
  1094.   /* 171 */ { 0, "shmsys" },
  1095.   { 0, }, /* 172 */
  1096.   { 0, }, /* 173 */
  1097.   { 0, }, /* 174 */
  1098.   { 0, }, /* 175 */
  1099.   { 0, }, /* 176 */
  1100.   { 0, }, /* 177 */
  1101.   { 0, }, /* 178 */
  1102.   { 0, }, /* 179 */
  1103.   { 0, }, /* 180 */
  1104.   /* 181 */ { 0, "setgid" },
  1105.   /* 182 */ { 0, "setegid" },
  1106.   /* 183 */ { 0, "seteuid" },
  1107.   /* 184 */ { 0, "lfs_bmapv" },
  1108.   /* 185 */ { 0, "lfs_markv" },
  1109.   /* 186 */ { 0, "lfs_segclean" },
  1110.   /* 187 */ { 0, "lfs_segwait" },
  1111.   /* 188 */ { do_stat, "stat" },
  1112.   /* 189 */ { do_fstat, "fstat" },
  1113.   /* 190 */ { do_lstat, "lstat" },
  1114.   /* 191 */ { 0, "pathconf" },
  1115.   /* 192 */ { 0, "fpathconf" },
  1116.   { 0, }, /* 193 */
  1117.   /* 194 */ { 0, "getrlimit" },
  1118.   /* 195 */ { 0, "setrlimit" },
  1119.   /* 196 */ { do_getdirentries, "getdirentries" },
  1120.   /* 197 */ { 0, "mmap" },
  1121.   /* 198 */ { do___syscall, "__syscall" },
  1122.   /* 199 */ { do_lseek, "lseek" },
  1123.   /* 200 */ { 0, "truncate" },
  1124.   /* 201 */ { 0, "ftruncate" },
  1125.   /* 202 */ { do___sysctl, "__sysctl" },
  1126.   /* 203 */ { 0, "mlock" },
  1127.   /* 204 */ { 0, "munlock" },
  1128. };
  1129.     
  1130. static char *(netbsd_error_names[]) = {
  1131.   /* 0 */ "ESUCCESS",
  1132.   /* 1 */ "EPERM",
  1133.   /* 2 */ "ENOENT",
  1134.   /* 3 */ "ESRCH",
  1135.   /* 4 */ "EINTR",
  1136.   /* 5 */ "EIO",
  1137.   /* 6 */ "ENXIO",
  1138.   /* 7 */ "E2BIG",
  1139.   /* 8 */ "ENOEXEC",
  1140.   /* 9 */ "EBADF",
  1141.   /* 10 */ "ECHILD",
  1142.   /* 11 */ "EDEADLK",
  1143.   /* 12 */ "ENOMEM",
  1144.   /* 13 */ "EACCES",
  1145.   /* 14 */ "EFAULT",
  1146.   /* 15 */ "ENOTBLK",
  1147.   /* 16 */ "EBUSY",
  1148.   /* 17 */ "EEXIST",
  1149.   /* 18 */ "EXDEV",
  1150.   /* 19 */ "ENODEV",
  1151.   /* 20 */ "ENOTDIR",
  1152.   /* 21 */ "EISDIR",
  1153.   /* 22 */ "EINVAL",
  1154.   /* 23 */ "ENFILE",
  1155.   /* 24 */ "EMFILE",
  1156.   /* 25 */ "ENOTTY",
  1157.   /* 26 */ "ETXTBSY",
  1158.   /* 27 */ "EFBIG",
  1159.   /* 28 */ "ENOSPC",
  1160.   /* 29 */ "ESPIPE",
  1161.   /* 30 */ "EROFS",
  1162.   /* 31 */ "EMLINK",
  1163.   /* 32 */ "EPIPE",
  1164.   /* 33 */ "EDOM",
  1165.   /* 34 */ "ERANGE",
  1166.   /* 35 */ "EAGAIN",
  1167.   /* 36 */ "EINPROGRESS",
  1168.   /* 37 */ "EALREADY",
  1169.   /* 38 */ "ENOTSOCK",
  1170.   /* 39 */ "EDESTADDRREQ",
  1171.   /* 40 */ "EMSGSIZE",
  1172.   /* 41 */ "EPROTOTYPE",
  1173.   /* 42 */ "ENOPROTOOPT",
  1174.   /* 43 */ "EPROTONOSUPPORT",
  1175.   /* 44 */ "ESOCKTNOSUPPORT",
  1176.   /* 45 */ "EOPNOTSUPP",
  1177.   /* 46 */ "EPFNOSUPPORT",
  1178.   /* 47 */ "EAFNOSUPPORT",
  1179.   /* 48 */ "EADDRINUSE",
  1180.   /* 49 */ "EADDRNOTAVAIL",
  1181.   /* 50 */ "ENETDOWN",
  1182.   /* 51 */ "ENETUNREACH",
  1183.   /* 52 */ "ENETRESET",
  1184.   /* 53 */ "ECONNABORTED",
  1185.   /* 54 */ "ECONNRESET",
  1186.   /* 55 */ "ENOBUFS",
  1187.   /* 56 */ "EISCONN",
  1188.   /* 57 */ "ENOTCONN",
  1189.   /* 58 */ "ESHUTDOWN",
  1190.   /* 59 */ "ETOOMANYREFS",
  1191.   /* 60 */ "ETIMEDOUT",
  1192.   /* 61 */ "ECONNREFUSED",
  1193.   /* 62 */ "ELOOP",
  1194.   /* 63 */ "ENAMETOOLONG",
  1195.   /* 64 */ "EHOSTDOWN",
  1196.   /* 65 */ "EHOSTUNREACH",
  1197.   /* 66 */ "ENOTEMPTY",
  1198.   /* 67 */ "EPROCLIM",
  1199.   /* 68 */ "EUSERS",
  1200.   /* 69 */ "EDQUOT",
  1201.   /* 70 */ "ESTALE",
  1202.   /* 71 */ "EREMOTE",
  1203.   /* 72 */ "EBADRPC",
  1204.   /* 73 */ "ERPCMISMATCH",
  1205.   /* 74 */ "EPROGUNAVAIL",
  1206.   /* 75 */ "EPROGMISMATCH",
  1207.   /* 76 */ "EPROCUNAVAIL",
  1208.   /* 77 */ "ENOLCK",
  1209.   /* 78 */ "ENOSYS",
  1210.   /* 79 */ "EFTYPE",
  1211.   /* 80 */ "EAUTH",
  1212.   /* 81 */ "ENEEDAUTH",
  1213.   /* 81 */ "ELAST",
  1214. };
  1215.  
  1216. static char *(netbsd_signal_names[]) = {
  1217.   /* 0 */ 0,
  1218.   /* 1 */ "SIGHUP",
  1219.   /* 2 */ "SIGINT",
  1220.   /* 3 */ "SIGQUIT",
  1221.   /* 4 */ "SIGILL",
  1222.   /* 5 */ "SIGTRAP",
  1223.   /* 6 */ "SIGABRT",
  1224.   /* 7 */ "SIGEMT",
  1225.   /* 8 */ "SIGFPE",
  1226.   /* 9 */ "SIGKILL",
  1227.   /* 10 */ "SIGBUS",
  1228.   /* 11 */ "SIGSEGV",
  1229.   /* 12 */ "SIGSYS",
  1230.   /* 13 */ "SIGPIPE",
  1231.   /* 14 */ "SIGALRM",
  1232.   /* 15 */ "SIGTERM",
  1233.   /* 16 */ "SIGURG",
  1234.   /* 17 */ "SIGSTOP",
  1235.   /* 18 */ "SIGTSTP",
  1236.   /* 19 */ "SIGCONT",
  1237.   /* 20 */ "SIGCHLD",
  1238.   /* 21 */ "SIGTTIN",
  1239.   /* 22 */ "SIGTTOU",
  1240.   /* 23 */ "SIGIO",
  1241.   /* 24 */ "SIGXCPU",
  1242.   /* 25 */ "SIGXFSZ",
  1243.   /* 26 */ "SIGVTALRM",
  1244.   /* 27 */ "SIGPROF",
  1245.   /* 28 */ "SIGWINCH",
  1246.   /* 29 */ "SIGINFO",
  1247.   /* 30 */ "SIGUSR1",
  1248.   /* 31 */ "SIGUSR2",
  1249. };
  1250.  
  1251. static emul_syscall emul_netbsd_syscalls = {
  1252.   netbsd_descriptors,
  1253.   sizeof(netbsd_descriptors) / sizeof(netbsd_descriptors[0]),
  1254.   netbsd_error_names,
  1255.   sizeof(netbsd_error_names) / sizeof(netbsd_error_names[0]),
  1256.   netbsd_signal_names,
  1257.   sizeof(netbsd_signal_names) / sizeof(netbsd_signal_names[0]),
  1258. };
  1259.  
  1260.  
  1261. /* NetBSD's os_emul interface, most are just passed on to the generic
  1262.    syscall stuff */
  1263.  
  1264. static os_emul_data *
  1265. emul_netbsd_create(device *root,
  1266.            bfd *image,
  1267.            const char *name)
  1268. {
  1269.   unsigned_word top_of_stack;
  1270.   unsigned stack_size;
  1271.   int elf_binary;
  1272.   os_emul_data *bsd_data;
  1273.   device *vm;
  1274.  
  1275.   /* check that this emulation is really for us */
  1276.   if (name != NULL && strcmp(name, "netbsd") != 0)
  1277.     return NULL;
  1278.   if (image == NULL)
  1279.     return NULL;
  1280.  
  1281.  
  1282.   /* merge any emulation specific entries into the device tree */
  1283.  
  1284.   /* establish a few defaults */
  1285.   if (image->xvec->flavour == bfd_target_elf_flavour) {
  1286.     elf_binary = 1;
  1287.     top_of_stack = 0xe0000000;
  1288.     stack_size =   0x00100000;
  1289.   }
  1290.   else {
  1291.     elf_binary = 0;
  1292.     top_of_stack = 0x20000000;
  1293.     stack_size =   0x00100000;
  1294.   }
  1295.  
  1296.   /* options */
  1297.   emul_add_tree_options(root, image, "netbsd",
  1298.             (WITH_ENVIRONMENT == USER_ENVIRONMENT
  1299.              ? "user" : "virtual"),
  1300.             0 /*oea-interrupt-prefix*/);
  1301.  
  1302.   /* virtual memory - handles growth of stack/heap */
  1303.   vm = device_tree_add_parsed(root, "/openprom/vm@0x%lx",
  1304.                   (unsigned long)(top_of_stack - stack_size));
  1305.   device_tree_add_parsed(vm, "./stack-base 0x%lx",
  1306.              (unsigned long)(top_of_stack - stack_size));
  1307.   device_tree_add_parsed(vm, "./nr-bytes 0x%x", stack_size);
  1308.  
  1309.   device_tree_add_parsed(root, "/openprom/vm/map-binary/file-name %s",
  1310.              bfd_get_filename(image));
  1311.  
  1312.   /* finish the init */
  1313.   device_tree_add_parsed(root, "/openprom/init/register/pc 0x%lx",
  1314.              (unsigned long)bfd_get_start_address(image));
  1315.   device_tree_add_parsed(root, "/openprom/init/register/sp 0x%lx",
  1316.              (unsigned long)top_of_stack);
  1317.   device_tree_add_parsed(root, "/openprom/init/register/msr 0x%x",
  1318.              (device_find_boolean_property(root, "/options/little-endian?")
  1319.               ? msr_little_endian_mode
  1320.               : 0));
  1321.   device_tree_add_parsed(root, "/openprom/init/stack/stack-type %s",
  1322.              (elf_binary ? "elf" : "xcoff"));
  1323.  
  1324.   /* finally our emulation data */
  1325.   bsd_data = ZALLOC(os_emul_data);
  1326.   bsd_data->vm = vm;
  1327.   bsd_data->syscalls = &emul_netbsd_syscalls;
  1328.   return bsd_data;
  1329. }
  1330.  
  1331. static void
  1332. emul_netbsd_init(os_emul_data *emul_data,
  1333.          int nr_cpus)
  1334. {
  1335.   /* nothing yet */
  1336. }
  1337.  
  1338. static void
  1339. emul_netbsd_system_call(cpu *processor,
  1340.             unsigned_word cia,
  1341.             os_emul_data *emul_data)
  1342. {
  1343.   emul_do_system_call(emul_data,
  1344.               emul_data->syscalls,
  1345.               cpu_registers(processor)->gpr[0],
  1346.               3, /*r3 contains arg0*/
  1347.               processor,
  1348.               cia);
  1349. }
  1350.  
  1351. const os_emul emul_netbsd = {
  1352.   "netbsd",
  1353.   emul_netbsd_create,
  1354.   emul_netbsd_init,
  1355.   emul_netbsd_system_call,
  1356.   0, /*instruction_call*/
  1357.   0 /*data*/
  1358. };
  1359.  
  1360. #endif _EMUL_NETBSD_C_
  1361.