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