1 /* This file is part of the program psim. 2 3 Copyright (C) 1994-1998, 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 3 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, see <http://www.gnu.org/licenses/>. 17 18 */ 19 20 21 #ifndef _EMUL_NETBSD_C_ 22 #define _EMUL_NETBSD_C_ 23 24 25 /* Note: this module is called via a table. There is no benefit in 26 making it inline */ 27 28 #include "defs.h" 29 30 #include <string.h> 31 #include <sys/types.h> 32 #include <sys/stat.h> 33 #include <stdio.h> 34 #include <signal.h> 35 #include <fcntl.h> 36 #include <dirent.h> 37 #include <errno.h> 38 #include <sys/param.h> 39 #include <sys/time.h> 40 41 #include "emul_generic.h" 42 #include "emul_netbsd.h" 43 44 #ifdef HAVE_GETRUSAGE 45 #ifndef HAVE_SYS_RESOURCE_H 46 #undef HAVE_GETRUSAGE 47 #endif 48 #endif 49 50 #ifdef HAVE_GETRUSAGE 51 #include <sys/resource.h> 52 int getrusage(); 53 #endif 54 55 #if HAVE_SYS_IOCTL_H 56 #include <sys/ioctl.h> 57 #endif 58 59 #if HAVE_DIRENT_H 60 # include <dirent.h> 61 # define NAMLEN(dirent) strlen((dirent)->d_name) 62 #else 63 # define dirent direct 64 # define NAMLEN(dirent) (dirent)->d_namlen 65 # if HAVE_SYS_NDIR_H 66 # include <sys/ndir.h> 67 # endif 68 # if HAVE_SYS_DIR_H 69 # include <sys/dir.h> 70 # endif 71 # if HAVE_NDIR_H 72 # include <ndir.h> 73 # endif 74 #endif 75 76 #ifdef HAVE_UNISTD_H 77 #undef MAXPATHLEN /* sys/param.h might define this also */ 78 #include <unistd.h> 79 #endif 80 81 #include <stdlib.h> 82 83 #define WITH_NetBSD_HOST (NetBSD >= 199306) 84 #if WITH_NetBSD_HOST /* here NetBSD as that is what we're emulating */ 85 #include <sys/syscall.h> /* FIXME - should not be including this one */ 86 #include <sys/sysctl.h> 87 #include <sys/mount.h> 88 extern int getdirentries(int fd, char *buf, int nbytes, long *basep); 89 90 /* NetBSD post 2.0 has the statfs system call (if COMPAT_20), but does 91 not have struct statfs. In this case don't implement fstatfs. 92 FIXME: Should implement fstatvfs. */ 93 #ifndef HAVE_STRUCT_STATFS 94 #undef HAVE_FSTATFS 95 #endif 96 97 #else 98 99 /* If this is not netbsd, don't allow fstatfs or getdirentries at this time */ 100 #undef HAVE_FSTATFS 101 #undef HAVE_GETDIRENTRIES 102 #endif 103 104 #ifndef STATIC_INLINE_EMUL_NETBSD 105 #define STATIC_INLINE_EMUL_NETBSD STATIC_INLINE 106 #endif 107 108 109 #if WITH_NetBSD_HOST 110 #define SYS(X) ASSERT(call == (SYS_##X)) 111 #else 112 #define SYS(X) 113 #endif 114 115 #if WITH_NetBSD_HOST && (PATH_MAX != 1024) 116 #error "PATH_MAX not 1024" 117 #elif !defined(PATH_MAX) 118 #define PATH_MAX 1024 119 #endif 120 121 122 /* EMULATION 123 124 NetBSD - Emulation of user programs for NetBSD/PPC 125 126 DESCRIPTION 127 128 */ 129 130 131 /* NetBSD's idea of what is needed to implement emulations */ 132 133 struct _os_emul_data { 134 device *vm; 135 emul_syscall *syscalls; 136 }; 137 138 139 140 STATIC_INLINE_EMUL_NETBSD void 141 write_stat(unsigned_word addr, 142 struct stat buf, 143 cpu *processor, 144 unsigned_word cia) 145 { 146 H2T(buf.st_dev); 147 H2T(buf.st_ino); 148 H2T(buf.st_mode); 149 H2T(buf.st_nlink); 150 H2T(buf.st_uid); 151 H2T(buf.st_gid); 152 H2T(buf.st_size); 153 H2T(buf.st_atime); 154 /* H2T(buf.st_spare1); */ 155 H2T(buf.st_mtime); 156 /* H2T(buf.st_spare2); */ 157 H2T(buf.st_ctime); 158 /* H2T(buf.st_spare3); */ 159 #ifdef AC_STRUCT_ST_RDEV 160 H2T(buf.st_rdev); 161 #endif 162 #ifdef AC_STRUCT_ST_BLKSIZE 163 H2T(buf.st_blksize); 164 #endif 165 #ifdef AC_STRUCT_ST_BLOCKS 166 H2T(buf.st_blocks); 167 #endif 168 #if WITH_NetBSD_HOST 169 H2T(buf.st_flags); 170 H2T(buf.st_gen); 171 #endif 172 emul_write_buffer(&buf, addr, sizeof(buf), processor, cia); 173 } 174 175 176 #ifdef HAVE_FSTATFS 177 STATIC_INLINE_EMUL_NETBSD void 178 write_statfs(unsigned_word addr, 179 struct statfs buf, 180 cpu *processor, 181 unsigned_word cia) 182 { 183 H2T(buf.f_type); 184 H2T(buf.f_flags); 185 H2T(buf.f_bsize); 186 H2T(buf.f_iosize); 187 H2T(buf.f_blocks); 188 H2T(buf.f_bfree); 189 H2T(buf.f_bavail); 190 H2T(buf.f_files); 191 H2T(buf.f_ffree); 192 H2T(buf.f_fsid.val[0]); 193 H2T(buf.f_fsid.val[1]); 194 H2T(buf.f_owner); 195 /* f_spare[4]; */ 196 /* f_fstypename[MFSNAMELEN]; */ 197 /* f_mntonname[MNAMELEN]; */ 198 /* f_mntfromname[MNAMELEN]; */ 199 emul_write_buffer(&buf, addr, sizeof(buf), processor, cia); 200 } 201 #endif 202 203 204 STATIC_INLINE_EMUL_NETBSD void 205 write_timeval(unsigned_word addr, 206 struct timeval t, 207 cpu *processor, 208 unsigned_word cia) 209 { 210 H2T(t.tv_sec); 211 H2T(t.tv_usec); 212 emul_write_buffer(&t, addr, sizeof(t), processor, cia); 213 } 214 215 #ifdef HAVE_GETTIMEOFDAY 216 STATIC_INLINE_EMUL_NETBSD void 217 write_timezone(unsigned_word addr, 218 struct timezone tz, 219 cpu *processor, 220 unsigned_word cia) 221 { 222 H2T(tz.tz_minuteswest); 223 H2T(tz.tz_dsttime); 224 emul_write_buffer(&tz, addr, sizeof(tz), processor, cia); 225 } 226 #endif 227 228 #ifdef HAVE_GETDIRENTRIES 229 STATIC_INLINE_EMUL_NETBSD void 230 write_direntries(unsigned_word addr, 231 char *buf, 232 int nbytes, 233 cpu *processor, 234 unsigned_word cia) 235 { 236 while (nbytes > 0) { 237 struct dirent *out; 238 struct dirent *in = (struct dirent*)buf; 239 ASSERT(in->d_reclen <= nbytes); 240 out = (struct dirent*)zalloc(in->d_reclen); 241 memcpy(out/*dest*/, in/*src*/, in->d_reclen); 242 H2T(out->d_fileno); 243 H2T(out->d_reclen); 244 H2T(out->d_type); 245 H2T(out->d_namlen); 246 emul_write_buffer(out, addr, in->d_reclen, processor, cia); 247 nbytes -= in->d_reclen; 248 addr += in->d_reclen; 249 buf += in->d_reclen; 250 free(out); 251 } 252 } 253 #endif 254 255 256 #ifdef HAVE_GETRUSAGE 257 STATIC_INLINE_EMUL_NETBSD void 258 write_rusage(unsigned_word addr, 259 struct rusage rusage, 260 cpu *processor, 261 unsigned_word cia) 262 { 263 H2T(rusage.ru_utime.tv_sec); /* user time used */ 264 H2T(rusage.ru_utime.tv_usec); 265 H2T(rusage.ru_stime.tv_sec); /* system time used */ 266 H2T(rusage.ru_stime.tv_usec); 267 H2T(rusage.ru_maxrss); /* integral max resident set size */ 268 H2T(rusage.ru_ixrss); /* integral shared text memory size */ 269 H2T(rusage.ru_idrss); /* integral unshared data size */ 270 H2T(rusage.ru_isrss); /* integral unshared stack size */ 271 H2T(rusage.ru_minflt); /* page reclaims */ 272 H2T(rusage.ru_majflt); /* page faults */ 273 H2T(rusage.ru_nswap); /* swaps */ 274 H2T(rusage.ru_inblock); /* block input operations */ 275 H2T(rusage.ru_oublock); /* block output operations */ 276 H2T(rusage.ru_msgsnd); /* messages sent */ 277 H2T(rusage.ru_msgrcv); /* messages received */ 278 H2T(rusage.ru_nsignals); /* signals received */ 279 H2T(rusage.ru_nvcsw); /* voluntary context switches */ 280 H2T(rusage.ru_nivcsw); /* involuntary context switches */ 281 emul_write_buffer(&rusage, addr, sizeof(rusage), processor, cia); 282 } 283 #endif 284 285 286 /* File descriptors 0, 1, and 2 should not be closed. fd_closed[] 287 tracks whether these descriptors have been closed in do_close() 288 below. */ 289 290 static int fd_closed[3]; 291 292 /* Check for some occurrences of bad file descriptors. We only check 293 whether fd 0, 1, or 2 are "closed". By "closed" we mean that these 294 descriptors aren't actually closed, but are considered to be closed 295 by this layer. 296 297 Other checks are performed by the underlying OS call. */ 298 299 static int 300 fdbad (int fd) 301 { 302 if (fd >=0 && fd <= 2 && fd_closed[fd]) 303 { 304 errno = EBADF; 305 return -1; 306 } 307 return 0; 308 } 309 310 static void 311 do_exit(os_emul_data *emul, 312 unsigned call, 313 const int arg0, 314 cpu *processor, 315 unsigned_word cia) 316 { 317 int status = (int)cpu_registers(processor)->gpr[arg0]; 318 SYS(exit); 319 if (WITH_TRACE && ppc_trace[trace_os_emul]) 320 printf_filtered ("%d)\n", status); 321 322 cpu_halt(processor, cia, was_exited, status); 323 } 324 325 326 static void 327 do_read(os_emul_data *emul, 328 unsigned call, 329 const int arg0, 330 cpu *processor, 331 unsigned_word cia) 332 { 333 void *scratch_buffer; 334 int d = (int)cpu_registers(processor)->gpr[arg0]; 335 unsigned_word buf = cpu_registers(processor)->gpr[arg0+1]; 336 int nbytes = cpu_registers(processor)->gpr[arg0+2]; 337 int status; 338 SYS(read); 339 340 if (WITH_TRACE && ppc_trace[trace_os_emul]) 341 printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes); 342 343 /* get a tempoary bufer */ 344 scratch_buffer = zalloc(nbytes); 345 346 /* check if buffer exists by reading it */ 347 emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia); 348 349 /* read */ 350 #if 0 351 if (d == 0) { 352 status = fread (scratch_buffer, 1, nbytes, stdin); 353 if (status == 0 && ferror (stdin)) 354 status = -1; 355 } 356 #endif 357 status = fdbad (d); 358 if (status == 0) 359 status = read (d, scratch_buffer, nbytes); 360 361 emul_write_status(processor, status, errno); 362 if (status > 0) 363 emul_write_buffer(scratch_buffer, buf, status, processor, cia); 364 365 free(scratch_buffer); 366 } 367 368 369 static void 370 do_write(os_emul_data *emul, 371 unsigned call, 372 const int arg0, 373 cpu *processor, 374 unsigned_word cia) 375 { 376 void *scratch_buffer = NULL; 377 int d = (int)cpu_registers(processor)->gpr[arg0]; 378 unsigned_word buf = cpu_registers(processor)->gpr[arg0+1]; 379 int nbytes = cpu_registers(processor)->gpr[arg0+2]; 380 int status; 381 SYS(write); 382 383 if (WITH_TRACE && ppc_trace[trace_os_emul]) 384 printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes); 385 386 /* get a tempoary bufer */ 387 scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */ 388 389 /* copy in */ 390 emul_read_buffer(scratch_buffer, buf, nbytes, 391 processor, cia); 392 393 /* write */ 394 status = fdbad (d); 395 if (status == 0) 396 status = write(d, scratch_buffer, nbytes); 397 398 emul_write_status(processor, status, errno); 399 free(scratch_buffer); 400 401 flush_stdoutput(); 402 } 403 404 405 static void 406 do_open(os_emul_data *emul, 407 unsigned call, 408 const int arg0, 409 cpu *processor, 410 unsigned_word cia) 411 { 412 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 413 char path_buf[PATH_MAX]; 414 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 415 int flags = (int)cpu_registers(processor)->gpr[arg0+1]; 416 int mode = (int)cpu_registers(processor)->gpr[arg0+2]; 417 int hostflags; 418 int status; 419 420 if (WITH_TRACE && ppc_trace[trace_os_emul]) 421 printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode); 422 423 SYS(open); 424 425 /* Do some translation on 'flags' to match it to the host's version. */ 426 /* These flag values were taken from the NetBSD 1.4 header files. */ 427 if ((flags & 3) == 0) 428 hostflags = O_RDONLY; 429 else if ((flags & 3) == 1) 430 hostflags = O_WRONLY; 431 else 432 hostflags = O_RDWR; 433 if (flags & 0x00000008) 434 hostflags |= O_APPEND; 435 if (flags & 0x00000200) 436 hostflags |= O_CREAT; 437 if (flags & 0x00000400) 438 hostflags |= O_TRUNC; 439 if (flags & 0x00000800) 440 hostflags |= O_EXCL; 441 442 /* Can't combine these statements, cuz open sets errno. */ 443 status = open(path, hostflags, mode); 444 emul_write_status(processor, status, errno); 445 } 446 447 448 static void 449 do_close(os_emul_data *emul, 450 unsigned call, 451 const int arg0, 452 cpu *processor, 453 unsigned_word cia) 454 { 455 int d = (int)cpu_registers(processor)->gpr[arg0]; 456 int status; 457 458 if (WITH_TRACE && ppc_trace[trace_os_emul]) 459 printf_filtered ("%d", d); 460 461 SYS(close); 462 463 status = fdbad (d); 464 if (status == 0) 465 { 466 /* Do not close stdin, stdout, or stderr. GDB may still need access to 467 these descriptors. */ 468 if (d == 0 || d == 1 || d == 2) 469 { 470 fd_closed[d] = 1; 471 status = 0; 472 } 473 else 474 status = close(d); 475 } 476 477 emul_write_status(processor, status, errno); 478 } 479 480 481 static void 482 do_break(os_emul_data *emul, 483 unsigned call, 484 const int arg0, 485 cpu *processor, 486 unsigned_word cia) 487 { 488 /* just pass this onto the `vm' device */ 489 unsigned_word new_break = cpu_registers(processor)->gpr[arg0]; 490 int status; 491 492 if (WITH_TRACE && ppc_trace[trace_os_emul]) 493 printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]); 494 495 SYS(break); 496 status = device_ioctl(emul->vm, 497 processor, 498 cia, 499 device_ioctl_break, 500 new_break); /*ioctl-data*/ 501 emul_write_status(processor, 0, status); 502 } 503 504 505 #ifndef HAVE_GETPID 506 #define do_getpid 0 507 #else 508 static void 509 do_getpid(os_emul_data *emul, 510 unsigned call, 511 const int arg0, 512 cpu *processor, 513 unsigned_word cia) 514 { 515 SYS(getpid); 516 emul_write_status(processor, (int)getpid(), 0); 517 } 518 #endif 519 520 #ifndef HAVE_GETUID 521 #define do_getuid 0 522 #else 523 static void 524 do_getuid(os_emul_data *emul, 525 unsigned call, 526 const int arg0, 527 cpu *processor, 528 unsigned_word cia) 529 { 530 SYS(getuid); 531 emul_write_status(processor, (int)getuid(), 0); 532 } 533 #endif 534 535 #ifndef HAVE_GETEUID 536 #define do_geteuid 0 537 #else 538 static void 539 do_geteuid(os_emul_data *emul, 540 unsigned call, 541 const int arg0, 542 cpu *processor, 543 unsigned_word cia) 544 { 545 SYS(geteuid); 546 emul_write_status(processor, (int)geteuid(), 0); 547 } 548 #endif 549 550 #ifndef HAVE_KILL 551 #define do_kill 0 552 #else 553 static void 554 do_kill(os_emul_data *emul, 555 unsigned call, 556 const int arg0, 557 cpu *processor, 558 unsigned_word cia) 559 { 560 pid_t pid = cpu_registers(processor)->gpr[arg0]; 561 int sig = cpu_registers(processor)->gpr[arg0+1]; 562 563 if (WITH_TRACE && ppc_trace[trace_os_emul]) 564 printf_filtered ("%d, %d", (int)pid, sig); 565 566 SYS(kill); 567 printf_filtered("SYS_kill at 0x%lx - more to this than just being killed\n", 568 (long)cia); 569 cpu_halt(processor, cia, was_signalled, sig); 570 } 571 #endif 572 573 #ifndef HAVE_DUP 574 #define do_dup 0 575 #else 576 static void 577 do_dup(os_emul_data *emul, 578 unsigned call, 579 const int arg0, 580 cpu *processor, 581 unsigned_word cia) 582 { 583 int oldd = cpu_registers(processor)->gpr[arg0]; 584 int status = (fdbad (oldd) < 0) ? -1 : dup(oldd); 585 int err = errno; 586 587 if (WITH_TRACE && ppc_trace[trace_os_emul]) 588 printf_filtered ("%d", oldd); 589 590 SYS(dup); 591 emul_write_status(processor, status, err); 592 } 593 #endif 594 595 #ifndef HAVE_GETEGID 596 #define do_getegid 0 597 #else 598 static void 599 do_getegid(os_emul_data *emul, 600 unsigned call, 601 const int arg0, 602 cpu *processor, 603 unsigned_word cia) 604 { 605 SYS(getegid); 606 emul_write_status(processor, (int)getegid(), 0); 607 } 608 #endif 609 610 #ifndef HAVE_GETGID 611 #define do_getgid 0 612 #else 613 static void 614 do_getgid(os_emul_data *emul, 615 unsigned call, 616 const int arg0, 617 cpu *processor, 618 unsigned_word cia) 619 { 620 SYS(getgid); 621 emul_write_status(processor, (int)getgid(), 0); 622 } 623 #endif 624 625 #ifndef HAVE_SIGPROCMASK 626 #define do_sigprocmask 0 627 #else 628 static void 629 do_sigprocmask(os_emul_data *emul, 630 unsigned call, 631 const int arg0, 632 cpu *processor, 633 unsigned_word cia) 634 { 635 signed_word how = cpu_registers(processor)->gpr[arg0]; 636 unsigned_word set = cpu_registers(processor)->gpr[arg0+1]; 637 unsigned_word oset = cpu_registers(processor)->gpr[arg0+2]; 638 #ifdef SYS_sigprocmask 639 SYS(sigprocmask); 640 #endif 641 642 if (WITH_TRACE && ppc_trace[trace_os_emul]) 643 printf_filtered ("%ld, 0x%lx, 0x%lx", (long)how, (long)set, (long)oset); 644 645 emul_write_status(processor, 0, 0); 646 cpu_registers(processor)->gpr[4] = set; 647 } 648 #endif 649 650 #ifndef HAVE_IOCTL 651 #define do_ioctl 0 652 #else 653 static void 654 do_ioctl(os_emul_data *emul, 655 unsigned call, 656 const int arg0, 657 cpu *processor, 658 unsigned_word cia) 659 { 660 int d = cpu_registers(processor)->gpr[arg0]; 661 unsigned request = cpu_registers(processor)->gpr[arg0+1]; 662 unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2]; 663 664 #if !WITH_NetBSD_HOST 665 cpu_registers(processor)->gpr[arg0] = 0; /* just succeed */ 666 #else 667 unsigned dir = request & IOC_DIRMASK; 668 int status; 669 SYS(ioctl); 670 /* what we haven't done */ 671 if (dir & IOC_IN /* write into the io device */ 672 || dir & IOC_OUT 673 || !(dir & IOC_VOID)) 674 error("do_ioctl() read or write of parameter not implemented\n"); 675 status = fdbad (d); 676 if (status == 0) 677 status = ioctl(d, request, NULL); 678 emul_write_status(processor, status, errno); 679 #endif 680 681 if (WITH_TRACE && ppc_trace[trace_os_emul]) 682 printf_filtered ("%d, 0x%x, 0x%lx", d, request, (long)argp_addr); 683 } 684 #endif 685 686 #ifndef HAVE_UMASK 687 #define do_umask 0 688 #else 689 static void 690 do_umask(os_emul_data *emul, 691 unsigned call, 692 const int arg0, 693 cpu *processor, 694 unsigned_word cia) 695 { 696 int mask = cpu_registers(processor)->gpr[arg0]; 697 698 if (WITH_TRACE && ppc_trace[trace_os_emul]) 699 printf_filtered ("0%o", mask); 700 701 SYS(umask); 702 emul_write_status(processor, umask(mask), 0); 703 } 704 #endif 705 706 #ifndef HAVE_DUP2 707 #define do_dup2 0 708 #else 709 static void 710 do_dup2(os_emul_data *emul, 711 unsigned call, 712 const int arg0, 713 cpu *processor, 714 unsigned_word cia) 715 { 716 int oldd = cpu_registers(processor)->gpr[arg0]; 717 int newd = cpu_registers(processor)->gpr[arg0+1]; 718 int status = (fdbad (oldd) < 0) ? -1 : dup2(oldd, newd); 719 int err = errno; 720 721 if (WITH_TRACE && ppc_trace[trace_os_emul]) 722 printf_filtered ("%d, %d", oldd, newd); 723 724 SYS(dup2); 725 emul_write_status(processor, status, err); 726 } 727 #endif 728 729 #ifndef HAVE_FCNTL 730 #define do_fcntl 0 731 #else 732 static void 733 do_fcntl(os_emul_data *emul, 734 unsigned call, 735 const int arg0, 736 cpu *processor, 737 unsigned_word cia) 738 { 739 int fd = cpu_registers(processor)->gpr[arg0]; 740 int cmd = cpu_registers(processor)->gpr[arg0+1]; 741 int arg = cpu_registers(processor)->gpr[arg0+2]; 742 int status; 743 744 if (WITH_TRACE && ppc_trace[trace_os_emul]) 745 printf_filtered ("%d, %d, %d", fd, cmd, arg); 746 747 SYS(fcntl); 748 status = fdbad (fd); 749 if (status == 0) 750 status = fcntl(fd, cmd, arg); 751 emul_write_status(processor, status, errno); 752 } 753 #endif 754 755 #ifndef HAVE_GETTIMEOFDAY 756 #define do_gettimeofday 0 757 #else 758 static void 759 do_gettimeofday(os_emul_data *emul, 760 unsigned call, 761 const int arg0, 762 cpu *processor, 763 unsigned_word cia) 764 { 765 unsigned_word t_addr = cpu_registers(processor)->gpr[arg0]; 766 unsigned_word tz_addr = cpu_registers(processor)->gpr[arg0+1]; 767 struct timeval t; 768 struct timezone tz; 769 int status = gettimeofday(&t, (tz_addr != 0 ? &tz : NULL)); 770 int err = errno; 771 772 if (WITH_TRACE && ppc_trace[trace_os_emul]) 773 printf_filtered ("0x%lx, 0x%lx", (long)t_addr, (long)tz_addr); 774 775 SYS(__gettimeofday50); 776 emul_write_status(processor, status, err); 777 if (status == 0) { 778 if (t_addr != 0) 779 write_timeval(t_addr, t, processor, cia); 780 if (tz_addr != 0) 781 write_timezone(tz_addr, tz, processor, cia); 782 } 783 } 784 #endif 785 786 #ifndef HAVE_GETRUSAGE 787 #define do_getrusage 0 788 #else 789 static void 790 do_getrusage(os_emul_data *emul, 791 unsigned call, 792 const int arg0, 793 cpu *processor, 794 unsigned_word cia) 795 { 796 int who = cpu_registers(processor)->gpr[arg0]; 797 unsigned_word rusage_addr = cpu_registers(processor)->gpr[arg0+1]; 798 struct rusage rusage; 799 int status = getrusage(who, (rusage_addr != 0 ? &rusage : NULL)); 800 int err = errno; 801 802 if (WITH_TRACE && ppc_trace[trace_os_emul]) 803 printf_filtered ("%d, 0x%lx", who, (long)rusage_addr); 804 805 SYS(__getrusage50); 806 emul_write_status(processor, status, err); 807 if (status == 0) { 808 if (rusage_addr != 0) 809 write_rusage(rusage_addr, rusage, processor, cia); 810 } 811 } 812 #endif 813 814 815 #ifndef HAVE_FSTATFS 816 #define do_fstatfs 0 817 #else 818 static void 819 do_fstatfs(os_emul_data *emul, 820 unsigned call, 821 const int arg0, 822 cpu *processor, 823 unsigned_word cia) 824 { 825 int fd = cpu_registers(processor)->gpr[arg0]; 826 unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1]; 827 struct statfs buf; 828 int status; 829 830 if (WITH_TRACE && ppc_trace[trace_os_emul]) 831 printf_filtered ("%d, 0x%lx", fd, (long)buf_addr); 832 833 SYS(fstatfs); 834 status = fdbad (fd); 835 if (status == 0) 836 status = fstatfs(fd, (buf_addr == 0 ? NULL : &buf)); 837 emul_write_status(processor, status, errno); 838 if (status == 0) { 839 if (buf_addr != 0) 840 write_statfs(buf_addr, buf, processor, cia); 841 } 842 } 843 #endif 844 845 #ifndef HAVE_STAT 846 #define do_stat 0 847 #else 848 static void 849 do_stat(os_emul_data *emul, 850 unsigned call, 851 const int arg0, 852 cpu *processor, 853 unsigned_word cia) 854 { 855 char path_buf[PATH_MAX]; 856 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 857 unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1]; 858 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 859 struct stat buf; 860 int status; 861 #ifdef SYS_stat 862 SYS(stat); 863 #endif 864 status = stat(path, &buf); 865 emul_write_status(processor, status, errno); 866 if (status == 0) 867 write_stat(stat_buf_addr, buf, processor, cia); 868 } 869 #endif 870 871 #ifndef HAVE_FSTAT 872 #define do_fstat 0 873 #else 874 static void 875 do_fstat(os_emul_data *emul, 876 unsigned call, 877 const int arg0, 878 cpu *processor, 879 unsigned_word cia) 880 { 881 int fd = cpu_registers(processor)->gpr[arg0]; 882 unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1]; 883 struct stat buf = {}; 884 int status; 885 #ifdef SYS_fstat 886 SYS(fstat); 887 #endif 888 /* Can't combine these statements, cuz fstat sets errno. */ 889 status = fdbad (fd); 890 if (status == 0) 891 status = fstat(fd, &buf); 892 emul_write_status(processor, status, errno); 893 write_stat(stat_buf_addr, buf, processor, cia); 894 } 895 #endif 896 897 #ifndef HAVE_LSTAT 898 #define do_lstat 0 899 #else 900 static void 901 do_lstat(os_emul_data *emul, 902 unsigned call, 903 const int arg0, 904 cpu *processor, 905 unsigned_word cia) 906 { 907 char path_buf[PATH_MAX]; 908 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 909 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 910 unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1]; 911 struct stat buf; 912 int status; 913 #ifdef SYS_lstat 914 SYS(lstat); 915 #endif 916 /* Can't combine these statements, cuz lstat sets errno. */ 917 status = lstat(path, &buf); 918 emul_write_status(processor, status, errno); 919 write_stat(stat_buf_addr, buf, processor, cia); 920 } 921 #endif 922 923 #ifndef HAVE_GETDIRENTRIES 924 #define do_getdirentries 0 925 #else 926 static void 927 do_getdirentries(os_emul_data *emul, 928 unsigned call, 929 const int arg0, 930 cpu *processor, 931 unsigned_word cia) 932 { 933 int fd = cpu_registers(processor)->gpr[arg0]; 934 unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1]; 935 char *buf; 936 int nbytes = cpu_registers(processor)->gpr[arg0+2]; 937 unsigned_word basep_addr = cpu_registers(processor)->gpr[arg0+3]; 938 long basep; 939 int status; 940 #ifdef SYS_getdirentries 941 SYS(getdirentries); 942 #endif 943 if (buf_addr != 0 && nbytes >= 0) 944 buf = zalloc(nbytes); 945 else 946 buf = NULL; 947 status = getdirentries(fd, 948 (buf_addr == 0 ? NULL : buf), 949 nbytes, 950 (basep_addr == 0 ? NULL : &basep)); 951 emul_write_status(processor, status, errno); 952 if (basep_addr != 0) 953 emul_write_word(basep_addr, basep, processor, cia); 954 if (status > 0) 955 write_direntries(buf_addr, buf, status, processor, cia); 956 if (buf != NULL) 957 free(buf); 958 } 959 #endif 960 961 962 static void 963 do___syscall(os_emul_data *emul, 964 unsigned call, 965 const int arg0, 966 cpu *processor, 967 unsigned_word cia) 968 { 969 SYS(__syscall); 970 emul_do_system_call(emul, 971 emul->syscalls, 972 cpu_registers(processor)->gpr[arg0], 973 arg0 + 1, 974 processor, 975 cia); 976 } 977 978 #ifndef HAVE_LSEEK 979 #define do_lseek 0 980 #else 981 static void 982 do_lseek(os_emul_data *emul, 983 unsigned call, 984 const int arg0, 985 cpu *processor, 986 unsigned_word cia) 987 { 988 int fildes = cpu_registers(processor)->gpr[arg0]; 989 off_t offset = emul_read_gpr64(processor, arg0+2); 990 int whence = cpu_registers(processor)->gpr[arg0+4]; 991 off_t status; 992 SYS(lseek); 993 status = fdbad (fildes); 994 if (status == 0) 995 status = lseek(fildes, offset, whence); 996 if (status == -1) 997 emul_write_status(processor, -1, errno); 998 else { 999 emul_write_status(processor, 0, 0); /* success */ 1000 emul_write_gpr64(processor, 3, status); 1001 } 1002 } 1003 #endif 1004 1005 static void 1006 do___sysctl(os_emul_data *emul, 1007 unsigned call, 1008 const int arg0, 1009 cpu *processor, 1010 unsigned_word cia) 1011 { 1012 /* call the arguments by their real name */ 1013 unsigned_word name = cpu_registers(processor)->gpr[arg0]; 1014 signed_word namelen = cpu_registers(processor)->gpr[arg0+1]; 1015 unsigned_word oldp = cpu_registers(processor)->gpr[arg0+2]; 1016 unsigned_word oldlenp = cpu_registers(processor)->gpr[arg0+3]; 1017 signed_word oldlen; 1018 signed_word mib; 1019 signed_word int_val; 1020 SYS(__sysctl); 1021 1022 /* pluck out the management information base id */ 1023 if (namelen < 1) 1024 error("system_call()SYS___sysctl bad name[0]\n"); 1025 mib = vm_data_map_read_word(cpu_data_map(processor), 1026 name, 1027 processor, 1028 cia); 1029 name += sizeof(mib); 1030 1031 /* see what to do with it ... */ 1032 switch ((int)mib) { 1033 case 6/*CTL_HW*/: 1034 #if WITH_NetBSD_HOST && (CTL_HW != 6) 1035 # error "CTL_HW" 1036 #endif 1037 if (namelen < 2) 1038 error("system_call()SYS___sysctl - CTL_HW - bad name[1]\n"); 1039 mib = vm_data_map_read_word(cpu_data_map(processor), 1040 name, 1041 processor, 1042 cia); 1043 name += sizeof(mib); 1044 switch ((int)mib) { 1045 case 7/*HW_PAGESIZE*/: 1046 #if WITH_NetBSD_HOST && (HW_PAGESIZE != 7) 1047 # error "HW_PAGESIZE" 1048 #endif 1049 oldlen = vm_data_map_read_word(cpu_data_map(processor), 1050 oldlenp, 1051 processor, 1052 cia); 1053 if (sizeof(signed_word) > oldlen) 1054 error("system_call()sysctl - CTL_HW.HW_PAGESIZE - to small\n"); 1055 int_val = 8192; 1056 oldlen = sizeof(int_val); 1057 emul_write_word(oldp, int_val, processor, cia); 1058 emul_write_word(oldlenp, oldlen, processor, cia); 1059 break; 1060 default: 1061 error("sysctl() CTL_HW.%d unknown\n", mib); 1062 break; 1063 } 1064 break; 1065 default: 1066 error("sysctl() name[0]=%d unknown\n", (int)mib); 1067 break; 1068 } 1069 emul_write_status(processor, 0, 0); /* always succeed */ 1070 } 1071 1072 1073 1074 static emul_syscall_descriptor netbsd_descriptors[] = { 1075 /* 0 */ { 0, "syscall" }, 1076 /* 1 */ { do_exit, "exit" }, 1077 /* 2 */ { 0, "fork" }, 1078 /* 3 */ { do_read, "read" }, 1079 /* 4 */ { do_write, "write" }, 1080 /* 5 */ { do_open, "open" }, 1081 /* 6 */ { do_close, "close" }, 1082 { 0, }, /* 7 is old wait4 */ 1083 { 0, }, /* 8 is old creat */ 1084 /* 9 */ { 0, "link" }, 1085 /* 10 */ { 0, "unlink" }, 1086 { 0, }, /* 11 is obsolete execv */ 1087 /* 12 */ { 0, "chdir" }, 1088 /* 13 */ { 0, "fchdir" }, 1089 { 0, }, /* 14 is old mknod */ 1090 /* 15 */ { 0, "chmod" }, 1091 /* 16 */ { 0, "chown" }, 1092 /* 17 */ { do_break, "break" }, 1093 { 0, }, /* 18 is old getfsstat */ 1094 { 0, }, /* 19 is old lseek */ 1095 /* 20 */ { do_getpid, "getpid" }, 1096 { 0, }, /* 21 is old mount */ 1097 /* 22 */ { 0, "unmount" }, 1098 /* 23 */ { 0, "setuid" }, 1099 /* 24 */ { do_getuid, "getuid" }, 1100 /* 25 */ { do_geteuid, "geteuid" }, 1101 /* 26 */ { 0, "ptrace" }, 1102 /* 27 */ { 0, "recvmsg" }, 1103 /* 28 */ { 0, "sendmsg" }, 1104 /* 29 */ { 0, "recvfrom" }, 1105 /* 30 */ { 0, "accept" }, 1106 /* 31 */ { 0, "getpeername" }, 1107 /* 32 */ { 0, "getsockname" }, 1108 /* 33 */ { 0, "access" }, 1109 /* 34 */ { 0, "chflags" }, 1110 /* 35 */ { 0, "fchflags" }, 1111 /* 36 */ { 0, "sync" }, 1112 /* 37 */ { do_kill, "kill" }, 1113 { 0, }, /* 38 is old stat */ 1114 /* 39 */ { 0, "getppid" }, 1115 { 0, }, /* 40 is old lstat */ 1116 /* 41 */ { do_dup, "dup" }, 1117 /* 42 */ { 0, "pipe" }, 1118 /* 43 */ { do_getegid, "getegid" }, 1119 /* 44 */ { 0, "profil" }, 1120 /* 45 */ { 0, "ktrace" }, 1121 { 0, }, /* 46 is old sigaction */ 1122 /* 47 */ { do_getgid, "getgid" }, 1123 { 0, }, /* 48 is old sigprocmask */ 1124 /* 49 */ { 0, "getlogin" }, 1125 /* 50 */ { 0, "setlogin" }, 1126 /* 51 */ { 0, "acct" }, 1127 { 0, }, /* 52 is old sigpending */ 1128 { 0, }, /* 53 is old sigaltstack */ 1129 /* 54 */ { do_ioctl, "ioctl" }, 1130 { 0, }, /* 55 is old reboot */ 1131 /* 56 */ { 0, "revoke" }, 1132 /* 57 */ { 0, "symlink" }, 1133 /* 58 */ { 0, "readlink" }, 1134 /* 59 */ { 0, "execve" }, 1135 /* 60 */ { do_umask, "umask" }, 1136 /* 61 */ { 0, "chroot" }, 1137 { 0, }, /* 62 is old fstat */ 1138 { 0, }, /* 63 is old getkerninfo */ 1139 { 0, }, /* 64 is old getpagesize */ 1140 { 0, }, /* 65 is old msync */ 1141 /* 66 */ { 0, "vfork" }, 1142 { 0, }, /* 67 is obsolete vread */ 1143 { 0, }, /* 68 is obsolete vwrite */ 1144 /* 69 */ { 0, "sbrk" }, 1145 { 0, }, /* 70 is obsolete sstk */ 1146 { 0, }, /* 71 is old mmap */ 1147 { 0, }, /* 72 is obsolete vadvise */ 1148 /* 73 */ { 0, "munmap" }, 1149 /* 74 */ { 0, "mprotect" }, 1150 /* 75 */ { 0, "madvise" }, 1151 { 0, }, /* 76 is obsolete vhangup */ 1152 { 0, }, /* 77 is obsolete vlimit */ 1153 /* 78 */ { 0, "mincore" }, 1154 /* 79 */ { 0, "getgroups" }, 1155 /* 80 */ { 0, "setgroups" }, 1156 /* 81 */ { 0, "getpgrp" }, 1157 /* 82 */ { 0, "setpgid" }, 1158 { 0, }, /* 83 is old setitimer */ 1159 { 0, }, /* 84 is old wait */ 1160 { 0, }, /* 85 is old swapon */ 1161 { 0, }, /* 86 is old getitimer */ 1162 { 0, }, /* 87 is old gethostname */ 1163 { 0, }, /* 88 is old sethostname */ 1164 { 0, }, /* 89 is old getdtablesize */ 1165 { do_dup2, "dup2" }, 1166 { 0, }, /* 91 */ 1167 /* 92 */ { do_fcntl, "fcntl" }, 1168 { 0, }, /* 93 is old select */ 1169 { 0, }, /* 94 */ 1170 /* 95 */ { 0, "fsync" }, 1171 /* 96 */ { 0, "setpriority" }, 1172 { 0, }, /* 97 is old socket */ 1173 { 0, }, /* 98 is old connect */ 1174 { 0, }, /* 99 is old accept */ 1175 /* 100 */ { 0, "getpriority" }, 1176 { 0, }, /* 101 is old send */ 1177 { 0, }, /* 102 is old recv */ 1178 { 0, }, /* 103 is old sigreturn */ 1179 /* 104 */ { 0, "bind" }, 1180 /* 105 */ { 0, "setsockopt" }, 1181 /* 106 */ { 0, "listen" }, 1182 { 0, }, /* 107 is obsolete vtimes */ 1183 { 0, }, /* 108 is old sigvec */ 1184 { 0, }, /* 109 is old sigblock */ 1185 { 0, }, /* 110 is old sigsetmask */ 1186 { 0, }, /* 111 is old sigsuspend */ 1187 { 0, }, /* 112 is old sigstack */ 1188 { 0, }, /* 113 is old recvmsg */ 1189 { 0, }, /* 114 is old sendmsg */ 1190 /* - is obsolete vtrace */ { 0, "vtrace 115" }, 1191 { 0, }, /* 116 is old gettimeofday */ 1192 { 0, }, /* 117 is old getrusage */ 1193 /* 118 */ { 0, "getsockopt" }, 1194 /* - is obsolete resuba */ { 0, "resuba 119" }, 1195 /* 120 */ { 0, "readv" }, 1196 /* 121 */ { 0, "writev" }, 1197 { 0, }, /* 122 is old settimeofday */ 1198 /* 123 */ { 0, "fchown" }, 1199 /* 124 */ { 0, "fchmod" }, 1200 { 0, }, /* 125 is old recvfrom */ 1201 { 0, }, /* 126 is old setreuid */ 1202 { 0, }, /* 127 is old setregid */ 1203 /* 126 */ { 0, "setreuid" }, 1204 /* 127 */ { 0, "setregid" }, 1205 /* 128 */ { 0, "rename" }, 1206 { 0, }, /* 129 is old truncate */ 1207 { 0, }, /* 130 is old ftruncate */ 1208 /* 131 */ { 0, "flock" }, 1209 /* 132 */ { 0, "mkfifo" }, 1210 /* 133 */ { 0, "sendto" }, 1211 /* 134 */ { 0, "shutdown" }, 1212 /* 135 */ { 0, "socketpair" }, 1213 /* 136 */ { 0, "mkdir" }, 1214 /* 137 */ { 0, "rmdir" }, 1215 { 0, }, /* 138 is old utimes */ 1216 { 0, }, /* 139 is obsolete 4.2 sigreturn */ 1217 { 0, }, /* 140 is old adjtime */ 1218 { 0, }, /* 141 is old getpeername */ 1219 { 0, }, /* 142 is old gethostid */ 1220 { 0, }, /* 143 is old sethostid */ 1221 { 0, }, /* 144 is old getrlimit */ 1222 { 0, }, /* 145 is old setrlimit */ 1223 { 0, }, /* 146 is old killpg */ 1224 /* 147 */ { 0, "setsid" }, 1225 /* 148 */ { 0, "quotactl" }, 1226 { 0, }, /* 149 is old quota */ 1227 { 0, }, /* 150 is old getsockname */ 1228 { 0, }, /* 151 */ 1229 { 0, }, /* 152 */ 1230 { 0, }, /* 153 */ 1231 { 0, }, /* 154 */ 1232 /* 155 */ { 0, "nfssvc" }, 1233 { 0, }, /* 156 is old getdirentries */ 1234 { 0, }, /* 157 is old statfs */ 1235 { 0, }, /* 158 is old fstatfs */ 1236 { 0, }, /* 159 */ 1237 { 0, }, /* 160 */ 1238 { 0, }, /* 161 is old getfh */ 1239 { 0, }, /* 162 is old getdomainname */ 1240 { 0, }, /* 163 is old setdomainname */ 1241 { 0, }, /* 164 is old uname */ 1242 /* 165 */ { 0, "sysarch" }, 1243 { 0, }, /* 166 */ 1244 { 0, }, /* 167 */ 1245 { 0, }, /* 168 */ 1246 { 0, }, /* 169 is old semsys */ 1247 { 0, }, /* 170 is old msgsys */ 1248 { 0, }, /* 171 is old shmsys */ 1249 { 0, }, /* 172 */ 1250 /* 173 */ { 0, "pread" }, 1251 /* 174 */ { 0, "pwrite" }, 1252 { 0, }, /* 175 is old ntp_gettime */ 1253 /* 176 */ { 0, "ntp_adjtime" }, 1254 { 0, }, /* 177 */ 1255 { 0, }, /* 178 */ 1256 { 0, }, /* 179 */ 1257 { 0, }, /* 180 */ 1258 /* 181 */ { 0, "setgid" }, 1259 /* 182 */ { 0, "setegid" }, 1260 /* 183 */ { 0, "seteuid" }, 1261 /* 184 */ { 0, "lfs_bmapv" }, 1262 /* 185 */ { 0, "lfs_markv" }, 1263 /* 186 */ { 0, "lfs_segclean" }, 1264 /* 187 */ { 0, "lfs_segwait" }, 1265 { 0, }, /* 188 is old stat" */ 1266 { 0, }, /* 189 is old fstat */ 1267 { 0, }, /* 190 is old lstat */ 1268 /* 191 */ { 0, "pathconf" }, 1269 /* 192 */ { 0, "fpathconf" }, 1270 { 0, }, /* 193 */ 1271 /* 194 */ { 0, "getrlimit" }, 1272 /* 195 */ { 0, "setrlimit" }, 1273 { 0, }, /* 196 is old getdirentries */ 1274 /* 197 */ { 0, "mmap" }, 1275 /* 198 */ { do___syscall, "__syscall" }, 1276 /* 199 */ { do_lseek, "lseek" }, 1277 /* 200 */ { 0, "truncate" }, 1278 /* 201 */ { 0, "ftruncate" }, 1279 /* 202 */ { do___sysctl, "__sysctl" }, 1280 /* 203 */ { 0, "mlock" }, 1281 /* 204 */ { 0, "munlock" }, 1282 /* 205 */ { 0, "undelete" }, 1283 { 0, }, /* 206 is old futimes */ 1284 /* 207 */ { 0, "getpgid" }, 1285 /* 208 */ { 0, "reboot" }, 1286 /* 209 */ { 0, "poll" }, 1287 { 0, }, /* 210 */ 1288 { 0, }, /* 211 */ 1289 { 0, }, /* 212 */ 1290 { 0, }, /* 213 */ 1291 { 0, }, /* 214 */ 1292 { 0, }, /* 215 */ 1293 { 0, }, /* 216 */ 1294 { 0, }, /* 217 */ 1295 { 0, }, /* 218 */ 1296 { 0, }, /* 219 */ 1297 { 0, }, /* 220 is old semctl */ 1298 /* 221 */ { 0, "semget" }, 1299 /* 222 */ { 0, "semop" }, 1300 /* 223 */ { 0, "semconfig" }, 1301 { 0, }, /* 224 is old msgctl */ 1302 /* 225 */ { 0, "msgget" }, 1303 /* 226 */ { 0, "msgsnd" }, 1304 /* 227 */ { 0, "msgrcv" }, 1305 /* 228 */ { 0, "shmat" }, 1306 { 0, }, /* 229 is old shmctl */ 1307 /* 230 */ { 0, "shmdt" }, 1308 /* 231 */ { 0, "shmget" }, 1309 { 0, }, /* 232 is old clock_gettime */ 1310 { 0, }, /* 233 is old clock_settime */ 1311 { 0, }, /* 234 is old clock_getres */ 1312 /* 235 */ { 0, "timer_create" }, 1313 /* 236 */ { 0, "timer_delete" }, 1314 { 0, }, /* 237 is old timer_settime */ 1315 { 0, }, /* 238 is old timer_gettime */ 1316 /* 239 */ { 0, "timer_getoverrun" }, 1317 { 0, }, /* 240 is old nanosleep */ 1318 /* 241 */ { 0, "fdatasync" }, 1319 /* 242 */ { 0, "mlockall" }, 1320 /* 243 */ { 0, "munlockall" }, 1321 { 0, }, /* 244 is old sigtimedwait */ 1322 { 0, }, /* 245 */ 1323 /* 246 */ { 0, "modctl" }, 1324 /* 247 */ { 0, "_ksem_init" }, 1325 /* 248 */ { 0, "_ksem_open" }, 1326 /* 249 */ { 0, "_ksem_unlink" }, 1327 /* 250 */ { 0, "_ksem_close" }, 1328 /* 251 */ { 0, "_ksem_post" }, 1329 /* 252 */ { 0, "_ksem_wait" }, 1330 /* 253 */ { 0, "_ksem_trywait" }, 1331 /* 254 */ { 0, "_ksem_getvalue" }, 1332 /* 255 */ { 0, "_ksem_destroy" }, 1333 /* 256 */ { 0, "_ksem_timedwait" }, 1334 /* 257 */ { 0, "mq_open" }, 1335 /* 258 */ { 0, "mq_close" }, 1336 /* 259 */ { 0, "mq_unlink" }, 1337 /* 260 */ { 0, "mq_getattr" }, 1338 /* 261 */ { 0, "mq_setattr" }, 1339 /* 262 */ { 0, "mq_notify" }, 1340 /* 263 */ { 0, "mq_send" }, 1341 /* 264 */ { 0, "mq_receive" }, 1342 { 0, }, /* 265 is old mq_timedsend */ 1343 { 0, }, /* 266 is old mq_timedrecive */ 1344 { 0, }, /* 267 */ 1345 { 0, }, /* 268 */ 1346 { 0, }, /* 269 */ 1347 /* 270 */ { 0, "__posix_rename" }, 1348 /* 271 */ { 0, "swapctl" }, 1349 { 0, }, /* 272 is old getdents */ 1350 /* 273 */ { 0, "minherit" }, 1351 /* 274 */ { 0, "lchmod" }, 1352 /* 275 */ { 0, "lchown" }, 1353 { 0, }, /* 276 is old lutimes */ 1354 /* 277 */ { 0, "__msync13" }, 1355 { 0, }, /* 278 is old stat */ 1356 { 0, }, /* 279 is old fstat */ 1357 { 0, }, /* 280 is old lstat */ 1358 /* 281 */ { 0, "__sigaltstack13" }, 1359 /* 282 */ { 0, "__vfork14" }, 1360 /* 283 */ { 0, "__posix_chown" }, 1361 /* 284 */ { 0, "__posix_fchown" }, 1362 /* 285 */ { 0, "__posix_lchown" }, 1363 /* 286 */ { 0, "getsid" }, 1364 /* 287 */ { 0, "__clone" }, 1365 /* 288 */ { 0, "fktrace" }, 1366 /* 289 */ { 0, "preadv" }, 1367 /* 290 */ { 0, "pwritev" }, 1368 { 0, }, /* 291 is old sigaction */ 1369 /* 292 */ { 0, "__sigpending14" }, 1370 /* 293 */ { do_sigprocmask, "__sigprocmask14" }, 1371 /* 294 */ { 0, "__sigsuspend14" }, 1372 /* 295 */ { 0, "__sigreturn14" }, 1373 /* 296 */ { 0, "__getcwd" }, 1374 /* 297 */ { 0, "fchroot" }, 1375 { 0, }, /* 298 is old fhopen */ 1376 { 0, }, /* 299 is old fhstat */ 1377 { 0, }, /* 300 is old fhstatfs */ 1378 { 0, }, /* 301 is old semctl */ 1379 { 0, }, /* 302 is old msgctl */ 1380 { 0, }, /* 303 is old shmctl */ 1381 /* 304 */ { 0, "lchflags" }, 1382 /* 305 */ { 0, "issetugid" }, 1383 /* 306 */ { 0, "utrace" }, 1384 /* 307 */ { 0, "getcontext" }, 1385 /* 308 */ { 0, "setcontext" }, 1386 /* 309 */ { 0, "_lwp_create" }, 1387 /* 310 */ { 0, "_lwp_exit" }, 1388 /* 311 */ { 0, "_lwp_self" }, 1389 /* 312 */ { 0, "_lwp_wait" }, 1390 /* 313 */ { 0, "_lwp_suspend" }, 1391 /* 314 */ { 0, "_lwp_continue" }, 1392 /* 315 */ { 0, "_lwp_wakeup" }, 1393 /* 316 */ { 0, "_lwp_getprivate" }, 1394 /* 317 */ { 0, "_lwp_setprivate" }, 1395 /* 318 */ { 0, "_lwp_kill" }, 1396 /* 319 */ { 0, "_lwp_detach" }, 1397 { 0, }, /* 320 is old _lwp_park */ 1398 /* 321 */ { 0, "_lwp_unpark" }, 1399 /* 322 */ { 0, "_lwp_unpark_all" }, 1400 /* 323 */ { 0, "_lwp_setname" }, 1401 /* 324 */ { 0, "_lwp_getname" }, 1402 /* 325 */ { 0, "_lwp_ctl" }, 1403 { 0, }, /* 326 */ 1404 { 0, }, /* 327 */ 1405 { 0, }, /* 328 */ 1406 { 0, }, /* 329 */ 1407 /* 330 */ { 0, "sa_register" }, 1408 /* 331 */ { 0, "sa_stacks" }, 1409 /* 332 */ { 0, "sa_enable" }, 1410 /* 333 */ { 0, "sa_setconcurrency" }, 1411 /* 334 */ { 0, "sa_yield" }, 1412 /* 335 */ { 0, "sa_preempt" }, 1413 { 0, }, /* 336 */ 1414 { 0, }, /* 337 */ 1415 { 0, }, /* 338 */ 1416 { 0, }, /* 339 */ 1417 /* 340 */ { 0, "__sigaction_sigtramp" }, 1418 /* 341 */ { 0, "pmc_get_info" }, 1419 /* 342 */ { 0, "pmc_control" }, 1420 /* 343 */ { 0, "rasctl" }, 1421 /* 344 */ { 0, "kqueue" }, 1422 { 0, }, /* 345 is old kevent */ 1423 /* 346 */ { 0, "_sched_setparam" }, 1424 /* 347 */ { 0, "_sched_getparam" }, 1425 /* 348 */ { 0, "_sched_setaffinity" }, 1426 /* 349 */ { 0, "_sched_getaffinity" }, 1427 /* 350 */ { 0, "sched_yield" }, 1428 { 0, }, /* 351 */ 1429 { 0, }, /* 352 */ 1430 { 0, }, /* 353 */ 1431 /* 354 */ { 0, "fsync_range" }, 1432 /* 355 */ { 0, "uuidgen" }, 1433 /* 356 */ { 0, "getvfsstat" }, 1434 /* 357 */ { 0, "statvfs1" }, 1435 /* 358 */ { 0, "fstatvfs1" }, 1436 { 0, }, /* 359 is old fhstatvfs1 */ 1437 /* 360 */ { 0, "extattrctl" }, 1438 /* 361 */ { 0, "extattr_set_file" }, 1439 /* 362 */ { 0, "extattr_get_file" }, 1440 /* 363 */ { 0, "extattr_delete_file" }, 1441 /* 364 */ { 0, "extattr_set_fd" }, 1442 /* 365 */ { 0, "extattr_get_fd" }, 1443 /* 366 */ { 0, "extattr_delete_fd" }, 1444 /* 367 */ { 0, "extattr_set_link" }, 1445 /* 368 */ { 0, "extattr_get_link" }, 1446 /* 369 */ { 0, "extattr_delete_link" }, 1447 /* 370 */ { 0, "extattr_list_fd" }, 1448 /* 371 */ { 0, "extattr_list_file" }, 1449 /* 372 */ { 0, "extattr_list_link" }, 1450 { 0, }, /* 373 is old pselect */ 1451 { 0, }, /* 374 is old pollts */ 1452 /* 375 */ { 0, "setxattr" }, 1453 /* 376 */ { 0, "lsetxattr" }, 1454 /* 377 */ { 0, "fsetxattr" }, 1455 /* 378 */ { 0, "getxattr" }, 1456 /* 379 */ { 0, "lgetxattr" }, 1457 /* 380 */ { 0, "fgetxattr" }, 1458 /* 381 */ { 0, "listxattr" }, 1459 /* 382 */ { 0, "llistxattr" }, 1460 /* 383 */ { 0, "flistxattr" }, 1461 /* 384 */ { 0, "removexattr" }, 1462 /* 385 */ { 0, "lremovexattr" }, 1463 /* 386 */ { 0, "fremovexattr" }, 1464 { 0, }, /* 387 is old stat */ 1465 { 0, }, /* 388 is old fstat */ 1466 { 0, }, /* 389 is old lstat */ 1467 /* 390 */ { do_getdirentries, "__getdents30" }, 1468 { 0, }, /* 391 is old posix_fadvise */ 1469 { 0, }, /* 392 is old fhstat */ 1470 { 0, }, /* 393 is old ntp_gettime */ 1471 /* 394 */ { 0, "__socket30" }, 1472 /* 395 */ { 0, "__getfh30" }, 1473 /* 396 */ { 0, "__fhopen40" }, 1474 /* 397 */ { 0, "__fhstatvfs140" }, 1475 { 0, }, /* 398 is old fhstat */ 1476 /* 399 */ { 0, "aio_cancel" }, 1477 /* 400 */ { 0, "aio_error" }, 1478 /* 401 */ { 0, "aio_fsync" }, 1479 /* 402 */ { 0, "aio_read" }, 1480 /* 403 */ { 0, "aio_return" }, 1481 { 0, }, /* 404 is old aio_suspend */ 1482 /* 405 */ { 0, "aio_write" }, 1483 /* 406 */ { 0, "lio_listio" }, 1484 { 0, }, /* 407 */ 1485 { 0, }, /* 408 */ 1486 { 0, }, /* 409 */ 1487 /* 410 */ { 0, "__mount50" }, 1488 /* 411 */ { 0, "mremap" }, 1489 /* 412 */ { 0, "pset_create" }, 1490 /* 413 */ { 0, "pset_destroy" }, 1491 /* 414 */ { 0, "pset_assign" }, 1492 /* 415 */ { 0, "_pset_bind" }, 1493 /* 416 */ { 0, "__posix_fadvise50" }, 1494 /* 417 */ { 0, "__select50" }, 1495 /* 418 */ { do_gettimeofday, "__gettimeofday50" }, 1496 /* 419 */ { 0, "__settimeofday50" }, 1497 /* 420 */ { 0, "__utimes50" }, 1498 /* 421 */ { 0, "__adjtime50" }, 1499 /* 422 */ { 0, "__lfs_segwait50" }, 1500 /* 423 */ { 0, "__futimes50" }, 1501 /* 424 */ { 0, "__lutimes50" }, 1502 /* 425 */ { 0, "__setitimer50" }, 1503 /* 426 */ { 0, "__getitimer50" }, 1504 /* 427 */ { 0, "__clock_gettime50" }, 1505 /* 428 */ { 0, "__clock_settime50" }, 1506 /* 429 */ { 0, "__clock_getres50" }, 1507 /* 430 */ { 0, "__nanosleep50" }, 1508 /* 431 */ { 0, "____sigtimedwait50" }, 1509 /* 432 */ { 0, "__mq_timedsend50" }, 1510 /* 433 */ { 0, "__mq_timedreceive50" }, 1511 /* 434 */ { 0, "____lwp_park50" }, 1512 /* 435 */ { 0, "__kevent50" }, 1513 /* 436 */ { 0, "__pselect50" }, 1514 /* 437 */ { 0, "__pollts50" }, 1515 /* 438 */ { 0, "__aio_suspend50" }, 1516 /* 439 */ { do_stat, "__stat50" }, 1517 /* 440 */ { do_fstat, "__fstat50" }, 1518 /* 441 */ { do_lstat, "__lstat50" }, 1519 /* 442 */ { 0, "____semctl50" }, 1520 /* 443 */ { 0, "__shmctl50" }, 1521 /* 444 */ { 0, "__msgctl50" }, 1522 /* 445 */ { do_getrusage, "__getrusage50" }, 1523 /* 446 */ { 0, "__timer_settime50" }, 1524 /* 447 */ { 0, "__timer_gettime50" }, 1525 /* 448 */ { 0, "__ntp_gettime50" }, 1526 /* 449 */ { 0, "__wait450" }, 1527 /* 450 */ { 0, "__mknod50" }, 1528 /* 451 */ { 0, "__fhstat50" }, 1529 { 0, }, /* 452 is obsolete 5.99 __quotactl50 */ 1530 /* 453 */ { 0, "pipe2" }, 1531 /* 454 */ { 0, "dup3" }, 1532 /* 455 */ { 0, "kqueue1" }, 1533 /* 456 */ { 0, "paccept" }, 1534 /* 457 */ { 0, "linkat" }, 1535 /* 458 */ { 0, "renameat" }, 1536 /* 459 */ { 0, "mkfifoat" }, 1537 /* 460 */ { 0, "mknodat" }, 1538 /* 461 */ { 0, "mkdirat" }, 1539 /* 462 */ { 0, "faccessat" }, 1540 /* 463 */ { 0, "fchmodat" }, 1541 /* 464 */ { 0, "fchownat" }, 1542 /* 465 */ { 0, "fexecve" }, 1543 /* 466 */ { 0, "fstatat" }, 1544 /* 467 */ { 0, "utimensat" }, 1545 /* 468 */ { 0, "openat" }, 1546 /* 469 */ { 0, "readlinkat" }, 1547 /* 470 */ { 0, "symlinkat" }, 1548 /* 471 */ { 0, "unlinkat" }, 1549 /* 472 */ { 0, "futimens" }, 1550 /* 473 */ { 0, "__quotactl" }, 1551 }; 1552 1553 static char *(netbsd_error_names[]) = { 1554 /* 0 */ "ESUCCESS", 1555 /* 1 */ "EPERM", 1556 /* 2 */ "ENOENT", 1557 /* 3 */ "ESRCH", 1558 /* 4 */ "EINTR", 1559 /* 5 */ "EIO", 1560 /* 6 */ "ENXIO", 1561 /* 7 */ "E2BIG", 1562 /* 8 */ "ENOEXEC", 1563 /* 9 */ "EBADF", 1564 /* 10 */ "ECHILD", 1565 /* 11 */ "EDEADLK", 1566 /* 12 */ "ENOMEM", 1567 /* 13 */ "EACCES", 1568 /* 14 */ "EFAULT", 1569 /* 15 */ "ENOTBLK", 1570 /* 16 */ "EBUSY", 1571 /* 17 */ "EEXIST", 1572 /* 18 */ "EXDEV", 1573 /* 19 */ "ENODEV", 1574 /* 20 */ "ENOTDIR", 1575 /* 21 */ "EISDIR", 1576 /* 22 */ "EINVAL", 1577 /* 23 */ "ENFILE", 1578 /* 24 */ "EMFILE", 1579 /* 25 */ "ENOTTY", 1580 /* 26 */ "ETXTBSY", 1581 /* 27 */ "EFBIG", 1582 /* 28 */ "ENOSPC", 1583 /* 29 */ "ESPIPE", 1584 /* 30 */ "EROFS", 1585 /* 31 */ "EMLINK", 1586 /* 32 */ "EPIPE", 1587 /* 33 */ "EDOM", 1588 /* 34 */ "ERANGE", 1589 /* 35 */ "EAGAIN", 1590 /* 36 */ "EINPROGRESS", 1591 /* 37 */ "EALREADY", 1592 /* 38 */ "ENOTSOCK", 1593 /* 39 */ "EDESTADDRREQ", 1594 /* 40 */ "EMSGSIZE", 1595 /* 41 */ "EPROTOTYPE", 1596 /* 42 */ "ENOPROTOOPT", 1597 /* 43 */ "EPROTONOSUPPORT", 1598 /* 44 */ "ESOCKTNOSUPPORT", 1599 /* 45 */ "EOPNOTSUPP", 1600 /* 46 */ "EPFNOSUPPORT", 1601 /* 47 */ "EAFNOSUPPORT", 1602 /* 48 */ "EADDRINUSE", 1603 /* 49 */ "EADDRNOTAVAIL", 1604 /* 50 */ "ENETDOWN", 1605 /* 51 */ "ENETUNREACH", 1606 /* 52 */ "ENETRESET", 1607 /* 53 */ "ECONNABORTED", 1608 /* 54 */ "ECONNRESET", 1609 /* 55 */ "ENOBUFS", 1610 /* 56 */ "EISCONN", 1611 /* 57 */ "ENOTCONN", 1612 /* 58 */ "ESHUTDOWN", 1613 /* 59 */ "ETOOMANYREFS", 1614 /* 60 */ "ETIMEDOUT", 1615 /* 61 */ "ECONNREFUSED", 1616 /* 62 */ "ELOOP", 1617 /* 63 */ "ENAMETOOLONG", 1618 /* 64 */ "EHOSTDOWN", 1619 /* 65 */ "EHOSTUNREACH", 1620 /* 66 */ "ENOTEMPTY", 1621 /* 67 */ "EPROCLIM", 1622 /* 68 */ "EUSERS", 1623 /* 69 */ "EDQUOT", 1624 /* 70 */ "ESTALE", 1625 /* 71 */ "EREMOTE", 1626 /* 72 */ "EBADRPC", 1627 /* 73 */ "ERPCMISMATCH", 1628 /* 74 */ "EPROGUNAVAIL", 1629 /* 75 */ "EPROGMISMATCH", 1630 /* 76 */ "EPROCUNAVAIL", 1631 /* 77 */ "ENOLCK", 1632 /* 78 */ "ENOSYS", 1633 /* 79 */ "EFTYPE", 1634 /* 80 */ "EAUTH", 1635 /* 81 */ "ENEEDAUTH", 1636 /* 82 */ "EIDRM", 1637 /* 83 */ "ENOMSG", 1638 /* 84 */ "EOVERFLOW", 1639 /* 85 */ "EILSEQ", 1640 /* 86 */ "ENOTSUP", 1641 /* 87 */ "ECANCELED", 1642 /* 88 */ "EBADMSG", 1643 /* 89 */ "ENODATA", 1644 /* 90 */ "ENOSR", 1645 /* 91 */ "ENOSTR", 1646 /* 92 */ "ETIME", 1647 /* 93 */ "ENOATTR", 1648 /* 94 */ "EMULTIHOP", 1649 /* 95 */ "ENOLINK", 1650 /* 96 */ "EPROTO", 1651 /* 97 */ "EOWNERDEAD", 1652 /* 98 */ "ENOTRECOVERABLE", 1653 /* 98 */ "ELAST", 1654 }; 1655 1656 static char *(netbsd_signal_names[]) = { 1657 /* 0 */ 0, 1658 /* 1 */ "SIGHUP", 1659 /* 2 */ "SIGINT", 1660 /* 3 */ "SIGQUIT", 1661 /* 4 */ "SIGILL", 1662 /* 5 */ "SIGTRAP", 1663 /* 6 */ "SIGABRT", 1664 /* 7 */ "SIGEMT", 1665 /* 8 */ "SIGFPE", 1666 /* 9 */ "SIGKILL", 1667 /* 10 */ "SIGBUS", 1668 /* 11 */ "SIGSEGV", 1669 /* 12 */ "SIGSYS", 1670 /* 13 */ "SIGPIPE", 1671 /* 14 */ "SIGALRM", 1672 /* 15 */ "SIGTERM", 1673 /* 16 */ "SIGURG", 1674 /* 17 */ "SIGSTOP", 1675 /* 18 */ "SIGTSTP", 1676 /* 19 */ "SIGCONT", 1677 /* 20 */ "SIGCHLD", 1678 /* 21 */ "SIGTTIN", 1679 /* 22 */ "SIGTTOU", 1680 /* 23 */ "SIGIO", 1681 /* 24 */ "SIGXCPU", 1682 /* 25 */ "SIGXFSZ", 1683 /* 26 */ "SIGVTALRM", 1684 /* 27 */ "SIGPROF", 1685 /* 28 */ "SIGWINCH", 1686 /* 29 */ "SIGINFO", 1687 /* 30 */ "SIGUSR1", 1688 /* 31 */ "SIGUSR2", 1689 /* 32 */ "SIGPWR", 1690 /* 33 */ "SIGRTMIN", 1691 /* 34 */ "SIGRTMIN+1", 1692 /* 35 */ "SIGRTMIN+2", 1693 /* 36 */ "SIGRTMIN+3", 1694 /* 37 */ "SIGRTMIN+4", 1695 /* 38 */ "SIGRTMIN+5", 1696 /* 39 */ "SIGRTMIN+6", 1697 /* 40 */ "SIGRTMIN+7", 1698 /* 41 */ "SIGRTMIN+8", 1699 /* 42 */ "SIGRTMIN+9", 1700 /* 43 */ "SIGRTMIN+10", 1701 /* 44 */ "SIGRTMIN+11", 1702 /* 45 */ "SIGRTMIN+12", 1703 /* 46 */ "SIGRTMIN+13", 1704 /* 47 */ "SIGRTMIN+14", 1705 /* 48 */ "SIGRTMIN+15", 1706 /* 49 */ "SIGRTMIN+16", 1707 /* 50 */ "SIGRTMIN+17", 1708 /* 51 */ "SIGRTMIN+18", 1709 /* 52 */ "SIGRTMIN+19", 1710 /* 53 */ "SIGRTMIN+20", 1711 /* 54 */ "SIGRTMIN+21", 1712 /* 55 */ "SIGRTMIN+22", 1713 /* 56 */ "SIGRTMIN+23", 1714 /* 57 */ "SIGRTMIN+24", 1715 /* 58 */ "SIGRTMIN+25", 1716 /* 59 */ "SIGRTMIN+26", 1717 /* 60 */ "SIGRTMIN+27", 1718 /* 61 */ "SIGRTMIN+28", 1719 /* 62 */ "SIGRTMIN+29", 1720 /* 63 */ "SIGRTMAX", 1721 }; 1722 1723 static emul_syscall emul_netbsd_syscalls = { 1724 netbsd_descriptors, 1725 ARRAY_SIZE (netbsd_descriptors), 1726 netbsd_error_names, 1727 ARRAY_SIZE (netbsd_error_names), 1728 netbsd_signal_names, 1729 ARRAY_SIZE (netbsd_signal_names), 1730 }; 1731 1732 1733 /* NetBSD's os_emul interface, most are just passed on to the generic 1734 syscall stuff */ 1735 1736 static os_emul_data * 1737 emul_netbsd_create(device *root, 1738 bfd *image, 1739 const char *name) 1740 { 1741 unsigned_word top_of_stack; 1742 unsigned stack_size; 1743 int elf_binary; 1744 os_emul_data *bsd_data; 1745 device *vm; 1746 char *filename; 1747 1748 /* check that this emulation is really for us */ 1749 if (name != NULL && strcmp(name, "netbsd") != 0) 1750 return NULL; 1751 if (image == NULL) 1752 return NULL; 1753 1754 1755 /* merge any emulation specific entries into the device tree */ 1756 1757 /* establish a few defaults */ 1758 if (image->xvec->flavour == bfd_target_elf_flavour) { 1759 elf_binary = 1; 1760 top_of_stack = 0xe0000000; 1761 stack_size = 0x00100000; 1762 } 1763 else { 1764 elf_binary = 0; 1765 top_of_stack = 0x20000000; 1766 stack_size = 0x00100000; 1767 } 1768 1769 /* options */ 1770 emul_add_tree_options(root, image, "netbsd", 1771 (WITH_ENVIRONMENT == USER_ENVIRONMENT 1772 ? "user" : "virtual"), 1773 0 /*oea-interrupt-prefix*/); 1774 1775 /* virtual memory - handles growth of stack/heap */ 1776 vm = tree_parse(root, "/openprom/vm"); 1777 tree_parse(vm, "./stack-base 0x%lx", 1778 (unsigned long)(top_of_stack - stack_size)); 1779 tree_parse(vm, "./nr-bytes 0x%x", stack_size); 1780 1781 filename = tree_quote_property (bfd_get_filename(image)); 1782 tree_parse(root, "/openprom/vm/map-binary/file-name %s", 1783 filename); 1784 free (filename); 1785 1786 /* finish the init */ 1787 tree_parse(root, "/openprom/init/register/pc 0x%lx", 1788 (unsigned long)bfd_get_start_address(image)); 1789 tree_parse(root, "/openprom/init/register/sp 0x%lx", 1790 (unsigned long)top_of_stack); 1791 tree_parse(root, "/openprom/init/register/msr 0x%x", 1792 ((tree_find_boolean_property(root, "/options/little-endian?") 1793 ? msr_little_endian_mode 1794 : 0) 1795 | (tree_find_boolean_property(root, "/openprom/options/floating-point?") 1796 ? (msr_floating_point_available 1797 | msr_floating_point_exception_mode_0 1798 | msr_floating_point_exception_mode_1) 1799 : 0))); 1800 tree_parse(root, "/openprom/init/stack/stack-type %s", 1801 (elf_binary ? "ppc-elf" : "ppc-xcoff")); 1802 1803 /* finally our emulation data */ 1804 bsd_data = ZALLOC(os_emul_data); 1805 bsd_data->vm = vm; 1806 bsd_data->syscalls = &emul_netbsd_syscalls; 1807 return bsd_data; 1808 } 1809 1810 static void 1811 emul_netbsd_init(os_emul_data *emul_data, 1812 int nr_cpus) 1813 { 1814 fd_closed[0] = 0; 1815 fd_closed[1] = 0; 1816 fd_closed[2] = 0; 1817 } 1818 1819 static void 1820 emul_netbsd_system_call(cpu *processor, 1821 unsigned_word cia, 1822 os_emul_data *emul_data) 1823 { 1824 emul_do_system_call(emul_data, 1825 emul_data->syscalls, 1826 cpu_registers(processor)->gpr[0], 1827 3, /*r3 contains arg0*/ 1828 processor, 1829 cia); 1830 } 1831 1832 const os_emul emul_netbsd = { 1833 "netbsd", 1834 emul_netbsd_create, 1835 emul_netbsd_init, 1836 emul_netbsd_system_call, 1837 0, /*instruction_call*/ 1838 0 /*data*/ 1839 }; 1840 1841 #endif /* _EMUL_NETBSD_C_ */ 1842