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