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