1 /* This file is part of the program psim. 2 3 Copyright (C) 1996-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_UNIX_C_ 22 #define _EMUL_UNIX_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_unix.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 #ifdef HAVE_SYS_TYPES_H 40 #include <sys/types.h> 41 #endif 42 43 #ifdef HAVE_SYS_TYPES_H 44 #include <sys/stat.h> 45 #else 46 #undef HAVE_STAT 47 #undef HAVE_LSTAT 48 #undef HAVE_FSTAT 49 #endif 50 51 #include <stdio.h> 52 #include <signal.h> 53 #include <errno.h> 54 55 #ifdef HAVE_FCNTL_H 56 #include <fcntl.h> 57 #endif 58 59 #ifdef HAVE_SYS_PARAM_H 60 #include <sys/param.h> 61 #endif 62 63 #ifdef HAVE_SYS_TIME_H 64 #include <sys/time.h> 65 #endif 66 67 #ifndef HAVE_TERMIOS_STRUCTURE 68 #undef HAVE_SYS_TERMIOS_H 69 #undef HAVE_TCGETATTR 70 #else 71 #ifndef HAVE_SYS_TERMIOS_H 72 #undef HAVE_TERMIOS_STRUCTURE 73 #endif 74 #endif 75 76 #ifdef HAVE_TERMIOS_STRUCTURE 77 #include <sys/termios.h> 78 79 /* If we have TERMIOS, use that for the termio structure, since some systems 80 don't like including both sys/termios.h and sys/termio.h at the same 81 time. */ 82 #undef HAVE_TERMIO_STRUCTURE 83 #undef TCGETA 84 #undef termio 85 #define termio termios 86 #endif 87 88 #ifndef HAVE_TERMIO_STRUCTURE 89 #undef HAVE_SYS_TERMIO_H 90 #else 91 #ifndef HAVE_SYS_TERMIO_H 92 #undef HAVE_TERMIO_STRUCTURE 93 #endif 94 #endif 95 96 #ifdef HAVE_TERMIO_STRUCTURE 97 #include <sys/termio.h> 98 #endif 99 100 #ifdef HAVE_GETRUSAGE 101 #ifndef HAVE_SYS_RESOURCE_H 102 #undef HAVE_GETRUSAGE 103 #endif 104 #endif 105 106 #ifdef HAVE_GETRUSAGE 107 #include <sys/resource.h> 108 int getrusage(); 109 #endif 110 111 #if HAVE_DIRENT_H 112 # include <dirent.h> 113 # define NAMLEN(dirent) strlen((dirent)->d_name) 114 #else 115 # define dirent direct 116 # define NAMLEN(dirent) (dirent)->d_namlen 117 # if HAVE_SYS_NDIR_H 118 # include <sys/ndir.h> 119 # endif 120 # if HAVE_SYS_DIR_H 121 # include <sys/dir.h> 122 # endif 123 # if HAVE_NDIR_H 124 # include <ndir.h> 125 # endif 126 #endif 127 128 #ifdef HAVE_UNISTD_H 129 #undef MAXPATHLEN /* sys/param.h might define this also */ 130 #include <unistd.h> 131 #endif 132 133 #ifdef HAVE_STDLIB_H 134 #include <stdlib.h> 135 #endif 136 137 #if defined(BSD) && !defined(errno) && (BSD < 199306) /* here BSD as just a bug */ 138 extern int errno; 139 #endif 140 141 #ifndef STATIC_INLINE_EMUL_UNIX 142 #define STATIC_INLINE_EMUL_UNIX STATIC_INLINE 143 #endif 144 145 #ifndef PATH_MAX 146 #define PATH_MAX 1024 147 #endif 148 149 #ifndef EINVAL 150 #define EINVAL -1 151 #endif 152 153 /* UNIX's idea of what is needed to implement emulations */ 154 155 struct _os_emul_data { 156 device *vm; 157 emul_syscall *syscalls; 158 }; 159 160 161 /* Emulation of simple UNIX system calls that are common on all systems. */ 162 163 /* Structures that are common agmonst the UNIX varients */ 164 struct unix_timeval { 165 signed32 tv_sec; /* seconds */ 166 signed32 tv_usec; /* microseconds */ 167 }; 168 169 struct unix_timezone { 170 signed32 tz_minuteswest; /* minutes west of Greenwich */ 171 signed32 tz_dsttime; /* type of dst correction */ 172 }; 173 174 #define UNIX_RUSAGE_SELF 0 175 #define UNIX_RUSAGE_CHILDREN (-1) 176 #define UNIX_RUSAGE_BOTH (-2) /* sys_wait4() uses this */ 177 178 struct unix_rusage { 179 struct unix_timeval ru_utime; /* user time used */ 180 struct unix_timeval ru_stime; /* system time used */ 181 signed32 ru_maxrss; /* maximum resident set size */ 182 signed32 ru_ixrss; /* integral shared memory size */ 183 signed32 ru_idrss; /* integral unshared data size */ 184 signed32 ru_isrss; /* integral unshared stack size */ 185 signed32 ru_minflt; /* any page faults not requiring I/O */ 186 signed32 ru_majflt; /* any page faults requiring I/O */ 187 signed32 ru_nswap; /* swaps */ 188 signed32 ru_inblock; /* block input operations */ 189 signed32 ru_oublock; /* block output operations */ 190 signed32 ru_msgsnd; /* messages sent */ 191 signed32 ru_msgrcv; /* messages received */ 192 signed32 ru_nsignals; /* signals received */ 193 signed32 ru_nvcsw; /* voluntary context switches */ 194 signed32 ru_nivcsw; /* involuntary " */ 195 }; 196 197 198 static void 199 do_unix_exit(os_emul_data *emul, 200 unsigned call, 201 const int arg0, 202 cpu *processor, 203 unsigned_word cia) 204 { 205 int status = (int)cpu_registers(processor)->gpr[arg0]; 206 if (WITH_TRACE && ppc_trace[trace_os_emul]) 207 printf_filtered ("%d)\n", status); 208 209 cpu_halt(processor, cia, was_exited, status); 210 } 211 212 213 static void 214 do_unix_read(os_emul_data *emul, 215 unsigned call, 216 const int arg0, 217 cpu *processor, 218 unsigned_word cia) 219 { 220 void *scratch_buffer; 221 int d = (int)cpu_registers(processor)->gpr[arg0]; 222 unsigned_word buf = cpu_registers(processor)->gpr[arg0+1]; 223 int nbytes = cpu_registers(processor)->gpr[arg0+2]; 224 int status; 225 226 if (WITH_TRACE && ppc_trace[trace_os_emul]) 227 printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes); 228 229 /* get a tempoary bufer */ 230 scratch_buffer = zalloc(nbytes); 231 232 /* check if buffer exists by reading it */ 233 emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia); 234 235 /* read */ 236 status = read (d, scratch_buffer, nbytes); 237 238 emul_write_status(processor, status, errno); 239 if (status > 0) 240 emul_write_buffer(scratch_buffer, buf, status, processor, cia); 241 242 free(scratch_buffer); 243 } 244 245 246 static void 247 do_unix_write(os_emul_data *emul, 248 unsigned call, 249 const int arg0, 250 cpu *processor, 251 unsigned_word cia) 252 { 253 void *scratch_buffer = NULL; 254 int d = (int)cpu_registers(processor)->gpr[arg0]; 255 unsigned_word buf = cpu_registers(processor)->gpr[arg0+1]; 256 int nbytes = cpu_registers(processor)->gpr[arg0+2]; 257 int status; 258 259 if (WITH_TRACE && ppc_trace[trace_os_emul]) 260 printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes); 261 262 /* get a tempoary bufer */ 263 scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */ 264 265 /* copy in */ 266 emul_read_buffer(scratch_buffer, buf, nbytes, 267 processor, cia); 268 269 /* write */ 270 status = write(d, scratch_buffer, nbytes); 271 emul_write_status(processor, status, errno); 272 free(scratch_buffer); 273 274 flush_stdoutput(); 275 } 276 277 278 static void 279 do_unix_open(os_emul_data *emul, 280 unsigned call, 281 const int arg0, 282 cpu *processor, 283 unsigned_word cia) 284 { 285 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 286 char path_buf[PATH_MAX]; 287 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 288 int flags = (int)cpu_registers(processor)->gpr[arg0+1]; 289 int mode = (int)cpu_registers(processor)->gpr[arg0+2]; 290 int status; 291 292 if (WITH_TRACE && ppc_trace[trace_os_emul]) 293 printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode); 294 295 status = open(path, flags, mode); 296 emul_write_status(processor, status, errno); 297 } 298 299 300 static void 301 do_unix_close(os_emul_data *emul, 302 unsigned call, 303 const int arg0, 304 cpu *processor, 305 unsigned_word cia) 306 { 307 int d = (int)cpu_registers(processor)->gpr[arg0]; 308 int status; 309 310 if (WITH_TRACE && ppc_trace[trace_os_emul]) 311 printf_filtered ("%d", d); 312 313 status = close(d); 314 emul_write_status(processor, status, errno); 315 } 316 317 318 static void 319 do_unix_break(os_emul_data *emul, 320 unsigned call, 321 const int arg0, 322 cpu *processor, 323 unsigned_word cia) 324 { 325 /* just pass this onto the `vm' device */ 326 unsigned_word new_break = cpu_registers(processor)->gpr[arg0]; 327 int status; 328 329 if (WITH_TRACE && ppc_trace[trace_os_emul]) 330 printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]); 331 332 status = device_ioctl(emul->vm, 333 processor, 334 cia, 335 device_ioctl_break, 336 new_break); /*ioctl-data*/ 337 338 emul_write_status(processor, 0, status); 339 } 340 341 #ifndef HAVE_ACCESS 342 #define do_unix_access 0 343 #else 344 static void 345 do_unix_access(os_emul_data *emul, 346 unsigned call, 347 const int arg0, 348 cpu *processor, 349 unsigned_word cia) 350 { 351 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 352 char path_buf[PATH_MAX]; 353 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 354 int mode = (int)cpu_registers(processor)->gpr[arg0+1]; 355 int status; 356 357 if (WITH_TRACE && ppc_trace[trace_os_emul]) 358 printf_filtered ("0x%lx [%s], 0x%x [0%o]", (long)path_addr, path, mode, mode); 359 360 status = access(path, mode); 361 emul_write_status(processor, status, errno); 362 } 363 #endif 364 365 #ifndef HAVE_GETPID 366 #define do_unix_getpid 0 367 #else 368 static void 369 do_unix_getpid(os_emul_data *emul, 370 unsigned call, 371 const int arg0, 372 cpu *processor, 373 unsigned_word cia) 374 { 375 pid_t status = getpid(); 376 emul_write_status(processor, (int)status, errno); 377 } 378 #endif 379 380 #ifndef HAVE_GETPPID 381 #define do_unix_getppid 0 382 #else 383 static void 384 do_unix_getppid(os_emul_data *emul, 385 unsigned call, 386 const int arg0, 387 cpu *processor, 388 unsigned_word cia) 389 { 390 pid_t status = getppid(); 391 emul_write_status(processor, (int)status, errno); 392 } 393 #endif 394 395 #if !defined(HAVE_GETPID) || !defined(HAVE_GETPPID) 396 #define do_unix_getpid2 0 397 #else 398 static void 399 do_unix_getpid2(os_emul_data *emul, 400 unsigned call, 401 const int arg0, 402 cpu *processor, 403 unsigned_word cia) 404 { 405 int pid = (int)getpid(); 406 int ppid = (int)getppid(); 407 emul_write2_status(processor, pid, ppid, errno); 408 } 409 #endif 410 411 #if !defined(HAVE_GETUID) || !defined(HAVE_GETEUID) 412 #define do_unix_getuid2 0 413 #else 414 static void 415 do_unix_getuid2(os_emul_data *emul, 416 unsigned call, 417 const int arg0, 418 cpu *processor, 419 unsigned_word cia) 420 { 421 uid_t uid = getuid(); 422 uid_t euid = geteuid(); 423 emul_write2_status(processor, (int)uid, (int)euid, errno); 424 } 425 #endif 426 427 #ifndef HAVE_GETUID 428 #define do_unix_getuid 0 429 #else 430 static void 431 do_unix_getuid(os_emul_data *emul, 432 unsigned call, 433 const int arg0, 434 cpu *processor, 435 unsigned_word cia) 436 { 437 uid_t status = getuid(); 438 emul_write_status(processor, (int)status, errno); 439 } 440 #endif 441 442 #ifndef HAVE_GETEUID 443 #define do_unix_geteuid 0 444 #else 445 static void 446 do_unix_geteuid(os_emul_data *emul, 447 unsigned call, 448 const int arg0, 449 cpu *processor, 450 unsigned_word cia) 451 { 452 uid_t status = geteuid(); 453 emul_write_status(processor, (int)status, errno); 454 } 455 #endif 456 457 #if 0 458 #ifndef HAVE_KILL 459 #define do_unix_kill 0 460 #else 461 static void 462 do_unix_kill(os_emul_data *emul, 463 unsigned call, 464 const int arg0, 465 cpu *processor, 466 unsigned_word cia) 467 { 468 pid_t pid = cpu_registers(processor)->gpr[arg0]; 469 int sig = cpu_registers(processor)->gpr[arg0+1]; 470 471 if (WITH_TRACE && ppc_trace[trace_os_emul]) 472 printf_filtered ("%d, %d", (int)pid, sig); 473 474 printf_filtered("SYS_kill at 0x%lx - more to this than just being killed\n", 475 (long)cia); 476 477 cpu_halt(processor, cia, was_signalled, sig); 478 } 479 #endif 480 #endif 481 482 #ifndef HAVE_DUP 483 #define do_unix_dup 0 484 #else 485 static void 486 do_unix_dup(os_emul_data *emul, 487 unsigned call, 488 const int arg0, 489 cpu *processor, 490 unsigned_word cia) 491 { 492 int oldd = cpu_registers(processor)->gpr[arg0]; 493 int status = dup(oldd); 494 int err = errno; 495 496 if (WITH_TRACE && ppc_trace[trace_os_emul]) 497 printf_filtered ("%d", oldd); 498 499 emul_write_status(processor, status, err); 500 } 501 #endif 502 503 #ifndef HAVE_DUP2 504 #define do_unix_dup2 0 505 #else 506 static void 507 do_unix_dup2(os_emul_data *emul, 508 unsigned call, 509 const int arg0, 510 cpu *processor, 511 unsigned_word cia) 512 { 513 int oldd = cpu_registers(processor)->gpr[arg0]; 514 int newd = cpu_registers(processor)->gpr[arg0+1]; 515 int status = dup2(oldd, newd); 516 int err = errno; 517 518 if (WITH_TRACE && ppc_trace[trace_os_emul]) 519 printf_filtered ("%d, %d", oldd, newd); 520 521 emul_write_status(processor, status, err); 522 } 523 #endif 524 525 #ifndef HAVE_LSEEK 526 #define do_unix_lseek 0 527 #else 528 static void 529 do_unix_lseek(os_emul_data *emul, 530 unsigned call, 531 const int arg0, 532 cpu *processor, 533 unsigned_word cia) 534 { 535 int fildes = (int)cpu_registers(processor)->gpr[arg0]; 536 off_t offset = (off_t)cpu_registers(processor)->gpr[arg0+1]; 537 int whence = (int)cpu_registers(processor)->gpr[arg0+2]; 538 off_t status; 539 540 if (WITH_TRACE && ppc_trace[trace_os_emul]) 541 printf_filtered ("%d %ld %d", fildes, (long)offset, whence); 542 543 status = lseek(fildes, offset, whence); 544 emul_write_status(processor, (int)status, errno); 545 } 546 #endif 547 548 549 #if !defined(HAVE_GETGID) || !defined(HAVE_GETEGID) 550 #define do_unix_getgid2 0 551 #else 552 static void 553 do_unix_getgid2(os_emul_data *emul, 554 unsigned call, 555 const int arg0, 556 cpu *processor, 557 unsigned_word cia) 558 { 559 gid_t gid = getgid(); 560 gid_t egid = getegid(); 561 emul_write2_status(processor, (int)gid, (int)egid, errno); 562 } 563 #endif 564 565 #ifndef HAVE_GETGID 566 #define do_unix_getgid 0 567 #else 568 static void 569 do_unix_getgid(os_emul_data *emul, 570 unsigned call, 571 const int arg0, 572 cpu *processor, 573 unsigned_word cia) 574 { 575 gid_t status = getgid(); 576 emul_write_status(processor, (int)status, errno); 577 } 578 #endif 579 580 #ifndef HAVE_GETEGID 581 #define do_unix_getegid 0 582 #else 583 static void 584 do_unix_getegid(os_emul_data *emul, 585 unsigned call, 586 const int arg0, 587 cpu *processor, 588 unsigned_word cia) 589 { 590 gid_t status = getegid(); 591 emul_write_status(processor, (int)status, errno); 592 } 593 #endif 594 595 #ifndef HAVE_UMASK 596 #define do_unix_umask 0 597 #else 598 static void 599 do_unix_umask(os_emul_data *emul, 600 unsigned call, 601 const int arg0, 602 cpu *processor, 603 unsigned_word cia) 604 { 605 mode_t mask = (mode_t)cpu_registers(processor)->gpr[arg0]; 606 int status = umask(mask); 607 608 if (WITH_TRACE && ppc_trace[trace_os_emul]) 609 printf_filtered ("0%o", (unsigned int)mask); 610 611 emul_write_status(processor, status, errno); 612 } 613 #endif 614 615 #ifndef HAVE_CHDIR 616 #define do_unix_chdir 0 617 #else 618 static void 619 do_unix_chdir(os_emul_data *emul, 620 unsigned call, 621 const int arg0, 622 cpu *processor, 623 unsigned_word cia) 624 { 625 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 626 char path_buf[PATH_MAX]; 627 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 628 int status; 629 630 if (WITH_TRACE && ppc_trace[trace_os_emul]) 631 printf_filtered ("0x%lx [%s]", (long)path_addr, path); 632 633 status = chdir(path); 634 emul_write_status(processor, status, errno); 635 } 636 #endif 637 638 #ifndef HAVE_LINK 639 #define do_unix_link 0 640 #else 641 static void 642 do_unix_link(os_emul_data *emul, 643 unsigned call, 644 const int arg0, 645 cpu *processor, 646 unsigned_word cia) 647 { 648 unsigned_word path1_addr = cpu_registers(processor)->gpr[arg0]; 649 char path1_buf[PATH_MAX]; 650 char *path1 = emul_read_string(path1_buf, path1_addr, PATH_MAX, processor, cia); 651 unsigned_word path2_addr = cpu_registers(processor)->gpr[arg0+1]; 652 char path2_buf[PATH_MAX]; 653 char *path2 = emul_read_string(path2_buf, path2_addr, PATH_MAX, processor, cia); 654 int status; 655 656 if (WITH_TRACE && ppc_trace[trace_os_emul]) 657 printf_filtered ("0x%lx [%s], 0x%lx [%s]", (long)path1_addr, path1, (long)path2_addr, path2); 658 659 status = link(path1, path2); 660 emul_write_status(processor, status, errno); 661 } 662 #endif 663 664 #ifndef HAVE_SYMLINK 665 #define do_unix_symlink 0 666 #else 667 static void 668 do_unix_symlink(os_emul_data *emul, 669 unsigned call, 670 const int arg0, 671 cpu *processor, 672 unsigned_word cia) 673 { 674 unsigned_word path1_addr = cpu_registers(processor)->gpr[arg0]; 675 char path1_buf[PATH_MAX]; 676 char *path1 = emul_read_string(path1_buf, path1_addr, PATH_MAX, processor, cia); 677 unsigned_word path2_addr = cpu_registers(processor)->gpr[arg0+1]; 678 char path2_buf[PATH_MAX]; 679 char *path2 = emul_read_string(path2_buf, path2_addr, PATH_MAX, processor, cia); 680 int status; 681 682 if (WITH_TRACE && ppc_trace[trace_os_emul]) 683 printf_filtered ("0x%lx [%s], 0x%lx [%s]", (long)path1_addr, path1, (long)path2_addr, path2); 684 685 status = symlink(path1, path2); 686 emul_write_status(processor, status, errno); 687 } 688 #endif 689 690 #ifndef HAVE_UNLINK 691 #define do_unix_unlink 0 692 #else 693 static void 694 do_unix_unlink(os_emul_data *emul, 695 unsigned call, 696 const int arg0, 697 cpu *processor, 698 unsigned_word cia) 699 { 700 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 701 char path_buf[PATH_MAX]; 702 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 703 int status; 704 705 if (WITH_TRACE && ppc_trace[trace_os_emul]) 706 printf_filtered ("0x%lx [%s]", (long)path_addr, path); 707 708 status = unlink(path); 709 emul_write_status(processor, status, errno); 710 } 711 #endif 712 713 #ifndef HAVE_MKDIR 714 #define do_unix_mkdir 0 715 #else 716 static void 717 do_unix_mkdir(os_emul_data *emul, 718 unsigned call, 719 const int arg0, 720 cpu *processor, 721 unsigned_word cia) 722 { 723 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 724 char path_buf[PATH_MAX]; 725 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 726 int mode = (int)cpu_registers(processor)->gpr[arg0+1]; 727 int status; 728 729 if (WITH_TRACE && ppc_trace[trace_os_emul]) 730 printf_filtered ("0x%lx [%s], 0%3o", (long)path_addr, path, mode); 731 732 #ifdef USE_WIN32API 733 status = mkdir(path); 734 #else 735 status = mkdir(path, mode); 736 #endif 737 emul_write_status(processor, status, errno); 738 } 739 #endif 740 741 #ifndef HAVE_RMDIR 742 #define do_unix_rmdir 0 743 #else 744 static void 745 do_unix_rmdir(os_emul_data *emul, 746 unsigned call, 747 const int arg0, 748 cpu *processor, 749 unsigned_word cia) 750 { 751 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 752 char path_buf[PATH_MAX]; 753 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 754 int status; 755 756 if (WITH_TRACE && ppc_trace[trace_os_emul]) 757 printf_filtered ("0x%lx [%s]", (long)path_addr, path); 758 759 status = rmdir(path); 760 emul_write_status(processor, status, errno); 761 } 762 #endif 763 764 #ifndef HAVE_TIME 765 #define do_unix_time 0 766 #else 767 static void 768 do_unix_time(os_emul_data *emul, 769 unsigned call, 770 const int arg0, 771 cpu *processor, 772 unsigned_word cia) 773 { 774 unsigned_word tp = cpu_registers(processor)->gpr[arg0]; 775 time_t now = time ((time_t *)0); 776 unsigned_word status = H2T_4(now); 777 778 if (WITH_TRACE && ppc_trace[trace_os_emul]) 779 printf_filtered ("0x%lx", (long)tp); 780 781 emul_write_status(processor, (int)status, errno); 782 783 if (tp) 784 emul_write_buffer(&status, tp, sizeof(status), processor, cia); 785 } 786 #endif 787 788 #if !defined(HAVE_GETTIMEOFDAY) || !defined(HAVE_SYS_TIME_H) 789 #define do_unix_gettimeofday 0 790 #else 791 static void 792 do_unix_gettimeofday(os_emul_data *emul, 793 unsigned call, 794 const int arg0, 795 cpu *processor, 796 unsigned_word cia) 797 { 798 unsigned_word tv = cpu_registers(processor)->gpr[arg0]; 799 unsigned_word tz = cpu_registers(processor)->gpr[arg0+1]; 800 struct unix_timeval target_timeval; 801 struct timeval host_timeval; 802 struct unix_timezone target_timezone; 803 struct timezone host_timezone; 804 int status; 805 806 if (WITH_TRACE && ppc_trace[trace_os_emul]) 807 printf_filtered ("0x%lx, 0x%lx", (long)tv, (long)tz); 808 809 /* Just in case the system doesn't set the timezone structure */ 810 host_timezone.tz_minuteswest = 0; 811 host_timezone.tz_dsttime = 0; 812 813 status = gettimeofday(&host_timeval, &host_timezone); 814 if (status >= 0) { 815 if (tv) { 816 target_timeval.tv_sec = H2T_4(host_timeval.tv_sec); 817 target_timeval.tv_usec = H2T_4(host_timeval.tv_usec); 818 emul_write_buffer((void *) &target_timeval, tv, sizeof(target_timeval), processor, cia); 819 } 820 821 if (tz) { 822 target_timezone.tz_minuteswest = H2T_4(host_timezone.tz_minuteswest); 823 target_timezone.tz_dsttime = H2T_4(host_timezone.tz_dsttime); 824 emul_write_buffer((void *) &target_timezone, tv, sizeof(target_timezone), processor, cia); 825 } 826 } 827 828 emul_write_status(processor, (int)status, errno); 829 } 830 #endif 831 832 833 #ifndef HAVE_GETRUSAGE 834 #define do_unix_getrusage 0 835 #else 836 static void 837 do_unix_getrusage(os_emul_data *emul, 838 unsigned call, 839 const int arg0, 840 cpu *processor, 841 unsigned_word cia) 842 { 843 signed_word who = (signed_word)cpu_registers(processor)->gpr[arg0]; 844 unsigned_word usage = cpu_registers(processor)->gpr[arg0+1]; 845 struct rusage host_rusage, host_rusage2; 846 struct unix_rusage target_rusage; 847 int status; 848 849 if (WITH_TRACE && ppc_trace[trace_os_emul]) 850 printf_filtered ("%ld, 0x%lx", (long)who, (long)usage); 851 852 switch (who) { 853 default: 854 status = -1; 855 errno = EINVAL; 856 break; 857 858 case UNIX_RUSAGE_SELF: 859 status = getrusage(RUSAGE_SELF, &host_rusage); 860 break; 861 862 case UNIX_RUSAGE_CHILDREN: 863 status = getrusage(RUSAGE_CHILDREN, &host_rusage); 864 break; 865 866 case UNIX_RUSAGE_BOTH: 867 status = getrusage(RUSAGE_SELF, &host_rusage); 868 if (status >= 0) { 869 status = getrusage(RUSAGE_CHILDREN, &host_rusage2); 870 if (status >= 0) { 871 host_rusage.ru_utime.tv_sec += host_rusage2.ru_utime.tv_sec; 872 host_rusage.ru_utime.tv_usec += host_rusage2.ru_utime.tv_usec; 873 host_rusage.ru_stime.tv_sec += host_rusage2.ru_stime.tv_sec; 874 host_rusage.ru_stime.tv_usec += host_rusage2.ru_stime.tv_usec; 875 host_rusage.ru_maxrss += host_rusage2.ru_maxrss; 876 host_rusage.ru_ixrss += host_rusage2.ru_ixrss; 877 host_rusage.ru_idrss += host_rusage2.ru_idrss; 878 host_rusage.ru_isrss += host_rusage2.ru_isrss; 879 host_rusage.ru_minflt += host_rusage2.ru_minflt; 880 host_rusage.ru_majflt += host_rusage2.ru_majflt; 881 host_rusage.ru_nswap += host_rusage2.ru_nswap; 882 host_rusage.ru_inblock += host_rusage2.ru_inblock; 883 host_rusage.ru_oublock += host_rusage2.ru_oublock; 884 host_rusage.ru_msgsnd += host_rusage2.ru_msgsnd; 885 host_rusage.ru_msgrcv += host_rusage2.ru_msgrcv; 886 host_rusage.ru_nsignals += host_rusage2.ru_nsignals; 887 host_rusage.ru_nvcsw += host_rusage2.ru_nvcsw; 888 host_rusage.ru_nivcsw += host_rusage2.ru_nivcsw; 889 } 890 } 891 } 892 893 if (status >= 0) { 894 target_rusage.ru_utime.tv_sec = H2T_4(host_rusage2.ru_utime.tv_sec); 895 target_rusage.ru_utime.tv_usec = H2T_4(host_rusage2.ru_utime.tv_usec); 896 target_rusage.ru_stime.tv_sec = H2T_4(host_rusage2.ru_stime.tv_sec); 897 target_rusage.ru_stime.tv_usec = H2T_4(host_rusage2.ru_stime.tv_usec); 898 target_rusage.ru_maxrss = H2T_4(host_rusage2.ru_maxrss); 899 target_rusage.ru_ixrss = H2T_4(host_rusage2.ru_ixrss); 900 target_rusage.ru_idrss = H2T_4(host_rusage2.ru_idrss); 901 target_rusage.ru_isrss = H2T_4(host_rusage2.ru_isrss); 902 target_rusage.ru_minflt = H2T_4(host_rusage2.ru_minflt); 903 target_rusage.ru_majflt = H2T_4(host_rusage2.ru_majflt); 904 target_rusage.ru_nswap = H2T_4(host_rusage2.ru_nswap); 905 target_rusage.ru_inblock = H2T_4(host_rusage2.ru_inblock); 906 target_rusage.ru_oublock = H2T_4(host_rusage2.ru_oublock); 907 target_rusage.ru_msgsnd = H2T_4(host_rusage2.ru_msgsnd); 908 target_rusage.ru_msgrcv = H2T_4(host_rusage2.ru_msgrcv); 909 target_rusage.ru_nsignals = H2T_4(host_rusage2.ru_nsignals); 910 target_rusage.ru_nvcsw = H2T_4(host_rusage2.ru_nvcsw); 911 target_rusage.ru_nivcsw = H2T_4(host_rusage2.ru_nivcsw); 912 emul_write_buffer((void *) &target_rusage, usage, sizeof(target_rusage), processor, cia); 913 } 914 915 emul_write_status(processor, status, errno); 916 } 917 #endif 918 919 920 static void 921 do_unix_nop(os_emul_data *emul, 922 unsigned call, 923 const int arg0, 924 cpu *processor, 925 unsigned_word cia) 926 { 927 if (WITH_TRACE && ppc_trace[trace_os_emul]) 928 printf_filtered ("0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", 929 (long)cpu_registers(processor)->gpr[arg0], 930 (long)cpu_registers(processor)->gpr[arg0+1], 931 (long)cpu_registers(processor)->gpr[arg0+2], 932 (long)cpu_registers(processor)->gpr[arg0+3], 933 (long)cpu_registers(processor)->gpr[arg0+4], 934 (long)cpu_registers(processor)->gpr[arg0+5]); 935 936 emul_write_status(processor, 0, errno); 937 } 938 939 940 /* Common code for initializing the system call stuff */ 941 942 static os_emul_data * 943 emul_unix_create(device *root, 944 bfd *image, 945 const char *name, 946 emul_syscall *syscall) 947 { 948 unsigned_word top_of_stack; 949 unsigned stack_size; 950 int elf_binary; 951 os_emul_data *data; 952 device *vm; 953 char *filename; 954 955 /* merge any emulation specific entries into the device tree */ 956 957 /* establish a few defaults */ 958 if (image->xvec->flavour == bfd_target_elf_flavour) { 959 elf_binary = 1; 960 top_of_stack = 0xe0000000; 961 stack_size = 0x00100000; 962 } 963 else { 964 elf_binary = 0; 965 top_of_stack = 0x20000000; 966 stack_size = 0x00100000; 967 } 968 969 /* options */ 970 emul_add_tree_options(root, image, name, 971 (WITH_ENVIRONMENT == USER_ENVIRONMENT 972 ? "user" : "virtual"), 973 0 /*oea-interrupt-prefix*/); 974 975 /* virtual memory - handles growth of stack/heap */ 976 vm = tree_parse(root, "/openprom/vm@0x%lx", 977 (unsigned long)(top_of_stack - stack_size)); 978 tree_parse(vm, "./stack-base 0x%lx", 979 (unsigned long)(top_of_stack - stack_size)); 980 tree_parse(vm, "./nr-bytes 0x%x", stack_size); 981 982 filename = tree_quote_property (bfd_get_filename(image)); 983 tree_parse(root, "/openprom/vm/map-binary/file-name %s", 984 filename); 985 free (filename); 986 987 /* finish the init */ 988 tree_parse(root, "/openprom/init/register/pc 0x%lx", 989 (unsigned long)bfd_get_start_address(image)); 990 tree_parse(root, "/openprom/init/register/sp 0x%lx", 991 (unsigned long)top_of_stack); 992 tree_parse(root, "/openprom/init/register/msr 0x%x", 993 ((tree_find_boolean_property(root, "/options/little-endian?") 994 ? msr_little_endian_mode 995 : 0) 996 | (tree_find_boolean_property(root, "/openprom/options/floating-point?") 997 ? (msr_floating_point_available 998 | msr_floating_point_exception_mode_0 999 | msr_floating_point_exception_mode_1) 1000 : 0))); 1001 tree_parse(root, "/openprom/init/stack/stack-type %s", 1002 (elf_binary ? "ppc-elf" : "ppc-xcoff")); 1003 1004 /* finally our emulation data */ 1005 data = ZALLOC(os_emul_data); 1006 data->vm = vm; 1007 data->syscalls = syscall; 1008 return data; 1009 } 1010 1011 1012 /* EMULATION 1013 1014 Solaris - Emulation of user programs for Solaris/PPC 1015 1016 DESCRIPTION 1017 1018 */ 1019 1020 1021 /* Solaris specific implementation */ 1022 1023 typedef signed32 solaris_uid_t; 1024 typedef signed32 solaris_gid_t; 1025 typedef signed32 solaris_off_t; 1026 typedef signed32 solaris_pid_t; 1027 typedef signed32 solaris_time_t; 1028 typedef unsigned32 solaris_dev_t; 1029 typedef unsigned32 solaris_ino_t; 1030 typedef unsigned32 solaris_mode_t; 1031 typedef unsigned32 solaris_nlink_t; 1032 1033 #ifdef HAVE_SYS_STAT_H 1034 #define SOLARIS_ST_FSTYPSZ 16 /* array size for file system type name */ 1035 1036 /* AIX 7.1 defines st_pad[123] to st_[amc]tim.tv_pad, respectively */ 1037 #undef st_pad1 1038 #undef st_pad2 1039 #undef st_pad3 1040 1041 struct solaris_stat { 1042 solaris_dev_t st_dev; 1043 signed32 st_pad1[3]; /* reserved for network id */ 1044 solaris_ino_t st_ino; 1045 solaris_mode_t st_mode; 1046 solaris_nlink_t st_nlink; 1047 solaris_uid_t st_uid; 1048 solaris_gid_t st_gid; 1049 solaris_dev_t st_rdev; 1050 signed32 st_pad2[2]; 1051 solaris_off_t st_size; 1052 signed32 st_pad3; /* future off_t expansion */ 1053 struct unix_timeval st_atim; 1054 struct unix_timeval st_mtim; 1055 struct unix_timeval st_ctim; 1056 signed32 st_blksize; 1057 signed32 st_blocks; 1058 char st_fstype[SOLARIS_ST_FSTYPSZ]; 1059 signed32 st_pad4[8]; /* expansion area */ 1060 }; 1061 1062 /* Convert from host stat structure to solaris stat structure */ 1063 STATIC_INLINE_EMUL_UNIX void 1064 convert_to_solaris_stat(unsigned_word addr, 1065 struct stat *host, 1066 cpu *processor, 1067 unsigned_word cia) 1068 { 1069 struct solaris_stat target; 1070 int i; 1071 1072 target.st_dev = H2T_4(host->st_dev); 1073 target.st_ino = H2T_4(host->st_ino); 1074 target.st_mode = H2T_4(host->st_mode); 1075 target.st_nlink = H2T_4(host->st_nlink); 1076 target.st_uid = H2T_4(host->st_uid); 1077 target.st_gid = H2T_4(host->st_gid); 1078 target.st_size = H2T_4(host->st_size); 1079 1080 #ifdef HAVE_ST_RDEV 1081 target.st_rdev = H2T_4(host->st_rdev); 1082 #else 1083 target.st_rdev = 0; 1084 #endif 1085 1086 #ifdef HAVE_ST_BLKSIZE 1087 target.st_blksize = H2T_4(host->st_blksize); 1088 #else 1089 target.st_blksize = 0; 1090 #endif 1091 1092 #ifdef HAVE_ST_BLOCKS 1093 target.st_blocks = H2T_4(host->st_blocks); 1094 #else 1095 target.st_blocks = 0; 1096 #endif 1097 1098 target.st_atim.tv_sec = H2T_4(host->st_atime); 1099 target.st_atim.tv_usec = 0; 1100 1101 target.st_ctim.tv_sec = H2T_4(host->st_ctime); 1102 target.st_ctim.tv_usec = 0; 1103 1104 target.st_mtim.tv_sec = H2T_4(host->st_mtime); 1105 target.st_mtim.tv_usec = 0; 1106 1107 for (i = 0; i < sizeof (target.st_pad1) / sizeof (target.st_pad1[0]); i++) 1108 target.st_pad1[i] = 0; 1109 1110 for (i = 0; i < sizeof (target.st_pad2) / sizeof (target.st_pad2[0]); i++) 1111 target.st_pad2[i] = 0; 1112 1113 target.st_pad3 = 0; 1114 1115 for (i = 0; i < sizeof (target.st_pad4) / sizeof (target.st_pad4[0]); i++) 1116 target.st_pad4[i] = 0; 1117 1118 /* For now, just punt and always say it is a ufs file */ 1119 strcpy (target.st_fstype, "ufs"); 1120 1121 emul_write_buffer(&target, addr, sizeof(target), processor, cia); 1122 } 1123 #endif /* HAVE_SYS_STAT_H */ 1124 1125 #ifndef HAVE_STAT 1126 #define do_solaris_stat 0 1127 #else 1128 static void 1129 do_solaris_stat(os_emul_data *emul, 1130 unsigned call, 1131 const int arg0, 1132 cpu *processor, 1133 unsigned_word cia) 1134 { 1135 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 1136 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; 1137 char path_buf[PATH_MAX]; 1138 struct stat buf; 1139 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 1140 int status; 1141 1142 if (WITH_TRACE && ppc_trace[trace_os_emul]) 1143 printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt); 1144 1145 status = stat (path, &buf); 1146 if (status == 0) 1147 convert_to_solaris_stat (stat_pkt, &buf, processor, cia); 1148 1149 emul_write_status(processor, status, errno); 1150 } 1151 #endif 1152 1153 #ifndef HAVE_LSTAT 1154 #define do_solaris_lstat 0 1155 #else 1156 static void 1157 do_solaris_lstat(os_emul_data *emul, 1158 unsigned call, 1159 const int arg0, 1160 cpu *processor, 1161 unsigned_word cia) 1162 { 1163 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 1164 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; 1165 char path_buf[PATH_MAX]; 1166 struct stat buf; 1167 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 1168 int status; 1169 1170 if (WITH_TRACE && ppc_trace[trace_os_emul]) 1171 printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt); 1172 1173 status = lstat (path, &buf); 1174 if (status == 0) 1175 convert_to_solaris_stat (stat_pkt, &buf, processor, cia); 1176 1177 emul_write_status(processor, status, errno); 1178 } 1179 #endif 1180 1181 #ifndef HAVE_FSTAT 1182 #define do_solaris_fstat 0 1183 #else 1184 static void 1185 do_solaris_fstat(os_emul_data *emul, 1186 unsigned call, 1187 const int arg0, 1188 cpu *processor, 1189 unsigned_word cia) 1190 { 1191 int fildes = (int)cpu_registers(processor)->gpr[arg0]; 1192 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; 1193 struct stat buf; 1194 int status; 1195 1196 if (WITH_TRACE && ppc_trace[trace_os_emul]) 1197 printf_filtered ("%d, 0x%lx", fildes, (long)stat_pkt); 1198 1199 status = fstat (fildes, &buf); 1200 if (status == 0) 1201 convert_to_solaris_stat (stat_pkt, &buf, processor, cia); 1202 1203 emul_write_status(processor, status, errno); 1204 } 1205 #endif 1206 1207 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE) 1208 #define SOLARIS_TIOC ('T'<<8) 1209 #define SOLARIS_NCC 8 1210 #define SOLARIS_NCCS 19 1211 1212 #define SOLARIS_VINTR 0 1213 #define SOLARIS_VQUIT 1 1214 #define SOLARIS_VERASE 2 1215 #define SOLARIS_VKILL 3 1216 #define SOLARIS_VEOF 4 1217 #define SOLARIS_VEOL 5 1218 #define SOLARIS_VEOL2 6 1219 #define SOLARIS_VSWTCH 7 1220 #define SOLARIS_VSTART 8 1221 #define SOLARIS_VSTOP 9 1222 #define SOLARIS_VSUSP 10 1223 #define SOLARIS_VDSUSP 11 1224 #define SOLARIS_VREPRINT 12 1225 #define SOLARIS_VDISCARD 13 1226 #define SOLARIS_VWERASE 14 1227 #define SOLARIS_VLNEXT 15 1228 #endif 1229 1230 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE) 1231 /* Convert to/from host termio structure */ 1232 1233 struct solaris_termio { 1234 unsigned16 c_iflag; /* input modes */ 1235 unsigned16 c_oflag; /* output modes */ 1236 unsigned16 c_cflag; /* control modes */ 1237 unsigned16 c_lflag; /* line discipline modes */ 1238 unsigned8 c_line; /* line discipline */ 1239 unsigned8 c_cc[SOLARIS_NCC]; /* control chars */ 1240 }; 1241 1242 STATIC_INLINE_EMUL_UNIX void 1243 convert_to_solaris_termio(unsigned_word addr, 1244 struct termio *host, 1245 cpu *processor, 1246 unsigned_word cia) 1247 { 1248 struct solaris_termio target; 1249 int i; 1250 1251 target.c_iflag = H2T_2 (host->c_iflag); 1252 target.c_oflag = H2T_2 (host->c_oflag); 1253 target.c_cflag = H2T_2 (host->c_cflag); 1254 target.c_lflag = H2T_2 (host->c_lflag); 1255 1256 #if defined(HAVE_TERMIO_CLINE) || defined(HAVE_TERMIOS_CLINE) 1257 target.c_line = host->c_line; 1258 #else 1259 target.c_line = 0; 1260 #endif 1261 1262 for (i = 0; i < SOLARIS_NCC; i++) 1263 target.c_cc[i] = 0; 1264 1265 #ifdef VINTR 1266 target.c_cc[SOLARIS_VINTR] = host->c_cc[VINTR]; 1267 #endif 1268 1269 #ifdef VQUIT 1270 target.c_cc[SOLARIS_VQUIT] = host->c_cc[VQUIT]; 1271 #endif 1272 1273 #ifdef VERASE 1274 target.c_cc[SOLARIS_VERASE] = host->c_cc[VERASE]; 1275 #endif 1276 1277 #ifdef VKILL 1278 target.c_cc[SOLARIS_VKILL] = host->c_cc[VKILL]; 1279 #endif 1280 1281 #ifdef VEOF 1282 target.c_cc[SOLARIS_VEOF] = host->c_cc[VEOF]; 1283 #endif 1284 1285 #ifdef VEOL 1286 target.c_cc[SOLARIS_VEOL] = host->c_cc[VEOL]; 1287 #endif 1288 1289 #ifdef VEOL2 1290 target.c_cc[SOLARIS_VEOL2] = host->c_cc[VEOL2]; 1291 #endif 1292 1293 #ifdef VSWTCH 1294 target.c_cc[SOLARIS_VSWTCH] = host->c_cc[VSWTCH]; 1295 1296 #else 1297 #ifdef VSWTC 1298 target.c_cc[SOLARIS_VSWTCH] = host->c_cc[VSWTC]; 1299 #endif 1300 #endif 1301 1302 emul_write_buffer(&target, addr, sizeof(target), processor, cia); 1303 } 1304 #endif /* HAVE_TERMIO_STRUCTURE || HAVE_TERMIOS_STRUCTURE */ 1305 1306 #ifdef HAVE_TERMIOS_STRUCTURE 1307 /* Convert to/from host termios structure */ 1308 1309 typedef unsigned32 solaris_tcflag_t; 1310 typedef unsigned8 solaris_cc_t; 1311 typedef unsigned32 solaris_speed_t; 1312 1313 struct solaris_termios { 1314 solaris_tcflag_t c_iflag; 1315 solaris_tcflag_t c_oflag; 1316 solaris_tcflag_t c_cflag; 1317 solaris_tcflag_t c_lflag; 1318 solaris_cc_t c_cc[SOLARIS_NCCS]; 1319 }; 1320 1321 STATIC_INLINE_EMUL_UNIX void 1322 convert_to_solaris_termios(unsigned_word addr, 1323 struct termios *host, 1324 cpu *processor, 1325 unsigned_word cia) 1326 { 1327 struct solaris_termios target; 1328 int i; 1329 1330 target.c_iflag = H2T_4 (host->c_iflag); 1331 target.c_oflag = H2T_4 (host->c_oflag); 1332 target.c_cflag = H2T_4 (host->c_cflag); 1333 target.c_lflag = H2T_4 (host->c_lflag); 1334 1335 for (i = 0; i < SOLARIS_NCCS; i++) 1336 target.c_cc[i] = 0; 1337 1338 #ifdef VINTR 1339 target.c_cc[SOLARIS_VINTR] = host->c_cc[VINTR]; 1340 #endif 1341 1342 #ifdef VQUIT 1343 target.c_cc[SOLARIS_VQUIT] = host->c_cc[VQUIT]; 1344 #endif 1345 1346 #ifdef VERASE 1347 target.c_cc[SOLARIS_VERASE] = host->c_cc[VERASE]; 1348 #endif 1349 1350 #ifdef VKILL 1351 target.c_cc[SOLARIS_VKILL] = host->c_cc[VKILL]; 1352 #endif 1353 1354 #ifdef VEOF 1355 target.c_cc[SOLARIS_VEOF] = host->c_cc[VEOF]; 1356 #endif 1357 1358 #ifdef VEOL 1359 target.c_cc[SOLARIS_VEOL] = host->c_cc[VEOL]; 1360 #endif 1361 1362 #ifdef VEOL2 1363 target.c_cc[SOLARIS_VEOL2] = host->c_cc[VEOL2]; 1364 #endif 1365 1366 #ifdef VSWTCH 1367 target.c_cc[SOLARIS_VSWTCH] = host->c_cc[VSWTCH]; 1368 1369 #else 1370 #ifdef VSWTC 1371 target.c_cc[SOLARIS_VSWTCH] = host->c_cc[VSWTC]; 1372 #endif 1373 #endif 1374 1375 #ifdef VSTART 1376 target.c_cc[SOLARIS_VSTART] = host->c_cc[VSTART]; 1377 #endif 1378 1379 #ifdef VSTOP 1380 target.c_cc[SOLARIS_VSTOP] = host->c_cc[VSTOP]; 1381 #endif 1382 1383 #ifdef VSUSP 1384 target.c_cc[SOLARIS_VSUSP] = host->c_cc[VSUSP]; 1385 #endif 1386 1387 #ifdef VDSUSP 1388 target.c_cc[SOLARIS_VDSUSP] = host->c_cc[VDSUSP]; 1389 #endif 1390 1391 #ifdef VREPRINT 1392 target.c_cc[SOLARIS_VREPRINT] = host->c_cc[VREPRINT]; 1393 #endif 1394 1395 #ifdef VDISCARD 1396 target.c_cc[SOLARIS_VDISCARD] = host->c_cc[VDISCARD]; 1397 #endif 1398 1399 #ifdef VWERASE 1400 target.c_cc[SOLARIS_VWERASE] = host->c_cc[VWERASE]; 1401 #endif 1402 1403 #ifdef VLNEXT 1404 target.c_cc[SOLARIS_VLNEXT] = host->c_cc[VLNEXT]; 1405 #endif 1406 1407 emul_write_buffer(&target, addr, sizeof(target), processor, cia); 1408 } 1409 #endif /* HAVE_TERMIOS_STRUCTURE */ 1410 1411 #ifndef HAVE_IOCTL 1412 #define do_solaris_ioctl 0 1413 #else 1414 static void 1415 do_solaris_ioctl(os_emul_data *emul, 1416 unsigned call, 1417 const int arg0, 1418 cpu *processor, 1419 unsigned_word cia) 1420 { 1421 int fildes = cpu_registers(processor)->gpr[arg0]; 1422 unsigned request = cpu_registers(processor)->gpr[arg0+1]; 1423 unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2]; 1424 int status = 0; 1425 const char *name = "<unknown>"; 1426 1427 #ifdef HAVE_TERMIOS_STRUCTURE 1428 struct termios host_termio; 1429 1430 #else 1431 #ifdef HAVE_TERMIO_STRUCTURE 1432 struct termio host_termio; 1433 #endif 1434 #endif 1435 1436 switch (request) 1437 { 1438 case 0: /* make sure we have at least one case */ 1439 default: 1440 status = -1; 1441 errno = EINVAL; 1442 break; 1443 1444 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE) 1445 #if defined(TCGETA) || defined(TCGETS) || defined(HAVE_TCGETATTR) 1446 case SOLARIS_TIOC | 1: /* TCGETA */ 1447 name = "TCGETA"; 1448 #ifdef HAVE_TCGETATTR 1449 status = tcgetattr(fildes, &host_termio); 1450 #elif defined(TCGETS) 1451 status = ioctl (fildes, TCGETS, &host_termio); 1452 #else 1453 status = ioctl (fildes, TCGETA, &host_termio); 1454 #endif 1455 if (status == 0) 1456 convert_to_solaris_termio (argp_addr, &host_termio, processor, cia); 1457 break; 1458 #endif /* TCGETA */ 1459 #endif /* HAVE_TERMIO_STRUCTURE */ 1460 1461 #ifdef HAVE_TERMIOS_STRUCTURE 1462 #if defined(TCGETS) || defined(HAVE_TCGETATTR) 1463 case SOLARIS_TIOC | 13: /* TCGETS */ 1464 name = "TCGETS"; 1465 #ifdef HAVE_TCGETATTR 1466 status = tcgetattr(fildes, &host_termio); 1467 #else 1468 status = ioctl (fildes, TCGETS, &host_termio); 1469 #endif 1470 if (status == 0) 1471 convert_to_solaris_termios (argp_addr, &host_termio, processor, cia); 1472 break; 1473 #endif /* TCGETS */ 1474 #endif /* HAVE_TERMIOS_STRUCTURE */ 1475 } 1476 1477 emul_write_status(processor, status, errno); 1478 1479 if (WITH_TRACE && ppc_trace[trace_os_emul]) 1480 printf_filtered ("%d, 0x%x [%s], 0x%lx", fildes, request, name, (long)argp_addr); 1481 } 1482 #endif /* HAVE_IOCTL */ 1483 1484 static emul_syscall_descriptor solaris_descriptors[] = { 1485 /* 0 */ { 0, "syscall" }, 1486 /* 1 */ { do_unix_exit, "exit" }, 1487 /* 2 */ { 0, "fork" }, 1488 /* 3 */ { do_unix_read, "read" }, 1489 /* 4 */ { do_unix_write, "write" }, 1490 /* 5 */ { do_unix_open, "open" }, 1491 /* 6 */ { do_unix_close, "close" }, 1492 /* 7 */ { 0, "wait" }, 1493 /* 8 */ { 0, "creat" }, 1494 /* 9 */ { do_unix_link, "link" }, 1495 /* 10 */ { do_unix_unlink, "unlink" }, 1496 /* 11 */ { 0, "exec" }, 1497 /* 12 */ { do_unix_chdir, "chdir" }, 1498 /* 13 */ { do_unix_time, "time" }, 1499 /* 14 */ { 0, "mknod" }, 1500 /* 15 */ { 0, "chmod" }, 1501 /* 16 */ { 0, "chown" }, 1502 /* 17 */ { do_unix_break, "brk" }, 1503 /* 18 */ { do_solaris_stat, "stat" }, 1504 /* 19 */ { do_unix_lseek, "lseek" }, 1505 /* 20 */ { do_unix_getpid2, "getpid" }, 1506 /* 21 */ { 0, "mount" }, 1507 /* 22 */ { 0, "umount" }, 1508 /* 23 */ { 0, "setuid" }, 1509 /* 24 */ { do_unix_getuid2, "getuid" }, 1510 /* 25 */ { 0, "stime" }, 1511 /* 26 */ { 0, "ptrace" }, 1512 /* 27 */ { 0, "alarm" }, 1513 /* 28 */ { do_solaris_fstat, "fstat" }, 1514 /* 29 */ { 0, "pause" }, 1515 /* 30 */ { 0, "utime" }, 1516 /* 31 */ { 0, "stty" }, 1517 /* 32 */ { 0, "gtty" }, 1518 /* 33 */ { do_unix_access, "access" }, 1519 /* 34 */ { 0, "nice" }, 1520 /* 35 */ { 0, "statfs" }, 1521 /* 36 */ { 0, "sync" }, 1522 /* 37 */ { 0, "kill" }, 1523 /* 38 */ { 0, "fstatfs" }, 1524 /* 39 */ { 0, "pgrpsys" }, 1525 /* 40 */ { 0, "xenix" }, 1526 /* 41 */ { do_unix_dup, "dup" }, 1527 /* 42 */ { 0, "pipe" }, 1528 /* 43 */ { 0, "times" }, 1529 /* 44 */ { 0, "profil" }, 1530 /* 45 */ { 0, "plock" }, 1531 /* 46 */ { 0, "setgid" }, 1532 /* 47 */ { do_unix_getgid2, "getgid" }, 1533 /* 48 */ { 0, "signal" }, 1534 /* 49 */ { 0, "msgsys" }, 1535 /* 50 */ { 0, "syssun" }, 1536 /* 51 */ { 0, "acct" }, 1537 /* 52 */ { 0, "shmsys" }, 1538 /* 53 */ { 0, "semsys" }, 1539 /* 54 */ { do_solaris_ioctl, "ioctl" }, 1540 /* 55 */ { 0, "uadmin" }, 1541 /* 56 */ { 0, 0 /* reserved for exch */ }, 1542 /* 57 */ { 0, "utssys" }, 1543 /* 58 */ { 0, "fdsync" }, 1544 /* 59 */ { 0, "execve" }, 1545 /* 60 */ { do_unix_umask, "umask" }, 1546 /* 61 */ { 0, "chroot" }, 1547 /* 62 */ { 0, "fcntl" }, 1548 /* 63 */ { 0, "ulimit" }, 1549 /* 64 */ { 0, 0 /* reserved for UNIX PC */ }, 1550 /* 64 */ { 0, 0 /* reserved for UNIX PC */ }, 1551 /* 65 */ { 0, 0 /* reserved for UNIX PC */ }, 1552 /* 66 */ { 0, 0 /* reserved for UNIX PC */ }, 1553 /* 67 */ { 0, 0 /* reserved for UNIX PC */ }, 1554 /* 68 */ { 0, 0 /* reserved for UNIX PC */ }, 1555 /* 69 */ { 0, 0 /* reserved for UNIX PC */ }, 1556 /* 70 */ { 0, 0 /* was advfs */ }, 1557 /* 71 */ { 0, 0 /* was unadvfs */ }, 1558 /* 72 */ { 0, 0 /* was rmount */ }, 1559 /* 73 */ { 0, 0 /* was rumount */ }, 1560 /* 74 */ { 0, 0 /* was rfstart */ }, 1561 /* 75 */ { 0, 0 /* was sigret */ }, 1562 /* 76 */ { 0, 0 /* was rdebug */ }, 1563 /* 77 */ { 0, 0 /* was rfstop */ }, 1564 /* 78 */ { 0, 0 /* was rfsys */ }, 1565 /* 79 */ { do_unix_rmdir, "rmdir" }, 1566 /* 80 */ { do_unix_mkdir, "mkdir" }, 1567 /* 81 */ { 0, "getdents" }, 1568 /* 82 */ { 0, 0 /* was libattach */ }, 1569 /* 83 */ { 0, 0 /* was libdetach */ }, 1570 /* 84 */ { 0, "sysfs" }, 1571 /* 85 */ { 0, "getmsg" }, 1572 /* 86 */ { 0, "putmsg" }, 1573 /* 87 */ { 0, "poll" }, 1574 /* 88 */ { do_solaris_lstat, "lstat" }, 1575 /* 89 */ { do_unix_symlink, "symlink" }, 1576 /* 90 */ { 0, "readlink" }, 1577 /* 91 */ { 0, "setgroups" }, 1578 /* 92 */ { 0, "getgroups" }, 1579 /* 93 */ { 0, "fchmod" }, 1580 /* 94 */ { 0, "fchown" }, 1581 /* 95 */ { 0, "sigprocmask" }, 1582 /* 96 */ { 0, "sigsuspend" }, 1583 /* 97 */ { do_unix_nop, "sigaltstack" }, 1584 /* 98 */ { do_unix_nop, "sigaction" }, 1585 /* 99 */ { 0, "sigpending" }, 1586 /* 100 */ { 0, "context" }, 1587 /* 101 */ { 0, "evsys" }, 1588 /* 102 */ { 0, "evtrapret" }, 1589 /* 103 */ { 0, "statvfs" }, 1590 /* 104 */ { 0, "fstatvfs" }, 1591 /* 105 */ { 0, 0 /* reserved */ }, 1592 /* 106 */ { 0, "nfssys" }, 1593 /* 107 */ { 0, "waitsys" }, 1594 /* 108 */ { 0, "sigsendsys" }, 1595 /* 109 */ { 0, "hrtsys" }, 1596 /* 110 */ { 0, "acancel" }, 1597 /* 111 */ { 0, "async" }, 1598 /* 112 */ { 0, "priocntlsys" }, 1599 /* 113 */ { 0, "pathconf" }, 1600 /* 114 */ { 0, "mincore" }, 1601 /* 115 */ { 0, "mmap" }, 1602 /* 116 */ { 0, "mprotect" }, 1603 /* 117 */ { 0, "munmap" }, 1604 /* 118 */ { 0, "fpathconf" }, 1605 /* 119 */ { 0, "vfork" }, 1606 /* 120 */ { 0, "fchdir" }, 1607 /* 121 */ { 0, "readv" }, 1608 /* 122 */ { 0, "writev" }, 1609 /* 123 */ { 0, "xstat" }, 1610 /* 124 */ { 0, "lxstat" }, 1611 /* 125 */ { 0, "fxstat" }, 1612 /* 126 */ { 0, "xmknod" }, 1613 /* 127 */ { 0, "clocal" }, 1614 /* 128 */ { 0, "setrlimit" }, 1615 /* 129 */ { 0, "getrlimit" }, 1616 /* 130 */ { 0, "lchown" }, 1617 /* 131 */ { 0, "memcntl" }, 1618 /* 132 */ { 0, "getpmsg" }, 1619 /* 133 */ { 0, "putpmsg" }, 1620 /* 134 */ { 0, "rename" }, 1621 /* 135 */ { 0, "uname" }, 1622 /* 136 */ { 0, "setegid" }, 1623 /* 137 */ { 0, "sysconfig" }, 1624 /* 138 */ { 0, "adjtime" }, 1625 /* 139 */ { 0, "systeminfo" }, 1626 /* 140 */ { 0, 0 /* reserved */ }, 1627 /* 141 */ { 0, "seteuid" }, 1628 /* 142 */ { 0, "vtrace" }, 1629 /* 143 */ { 0, "fork1" }, 1630 /* 144 */ { 0, "sigtimedwait" }, 1631 /* 145 */ { 0, "lwp_info" }, 1632 /* 146 */ { 0, "yield" }, 1633 /* 147 */ { 0, "lwp_sema_wait" }, 1634 /* 148 */ { 0, "lwp_sema_post" }, 1635 /* 149 */ { 0, 0 /* reserved */ }, 1636 /* 150 */ { 0, 0 /* reserved */ }, 1637 /* 151 */ { 0, 0 /* reserved */ }, 1638 /* 152 */ { 0, "modctl" }, 1639 /* 153 */ { 0, "fchroot" }, 1640 /* 154 */ { 0, "utimes" }, 1641 /* 155 */ { 0, "vhangup" }, 1642 /* 156 */ { do_unix_gettimeofday, "gettimeofday" }, 1643 /* 157 */ { 0, "getitimer" }, 1644 /* 158 */ { 0, "setitimer" }, 1645 /* 159 */ { 0, "lwp_create" }, 1646 /* 160 */ { 0, "lwp_exit" }, 1647 /* 161 */ { 0, "lwp_suspend" }, 1648 /* 162 */ { 0, "lwp_continue" }, 1649 /* 163 */ { 0, "lwp_kill" }, 1650 /* 164 */ { 0, "lwp_self" }, 1651 /* 165 */ { 0, "lwp_setprivate" }, 1652 /* 166 */ { 0, "lwp_getprivate" }, 1653 /* 167 */ { 0, "lwp_wait" }, 1654 /* 168 */ { 0, "lwp_mutex_unlock" }, 1655 /* 169 */ { 0, "lwp_mutex_lock" }, 1656 /* 170 */ { 0, "lwp_cond_wait" }, 1657 /* 171 */ { 0, "lwp_cond_signal" }, 1658 /* 172 */ { 0, "lwp_cond_broadcast" }, 1659 /* 173 */ { 0, "pread" }, 1660 /* 174 */ { 0, "pwrite" }, 1661 /* 175 */ { 0, "llseek" }, 1662 /* 176 */ { 0, "inst_sync" }, 1663 /* 177 */ { 0, 0 /* reserved */ }, 1664 /* 178 */ { 0, "kaio" }, 1665 /* 179 */ { 0, 0 /* reserved */ }, 1666 /* 180 */ { 0, 0 /* reserved */ }, 1667 /* 181 */ { 0, 0 /* reserved */ }, 1668 /* 182 */ { 0, 0 /* reserved */ }, 1669 /* 183 */ { 0, 0 /* reserved */ }, 1670 /* 184 */ { 0, "tsolsys" }, 1671 /* 185 */ { 0, "acl" }, 1672 /* 186 */ { 0, "auditsys" }, 1673 /* 187 */ { 0, "processor_bind" }, 1674 /* 188 */ { 0, "processor_info" }, 1675 /* 189 */ { 0, "p_online" }, 1676 /* 190 */ { 0, "sigqueue" }, 1677 /* 191 */ { 0, "clock_gettime" }, 1678 /* 192 */ { 0, "clock_settime" }, 1679 /* 193 */ { 0, "clock_getres" }, 1680 /* 194 */ { 0, "timer_create" }, 1681 /* 195 */ { 0, "timer_delete" }, 1682 /* 196 */ { 0, "timer_settime" }, 1683 /* 197 */ { 0, "timer_gettime" }, 1684 /* 198 */ { 0, "timer_getoverrun" }, 1685 /* 199 */ { 0, "nanosleep" }, 1686 /* 200 */ { 0, "facl" }, 1687 /* 201 */ { 0, "door" }, 1688 /* 202 */ { 0, "setreuid" }, 1689 /* 203 */ { 0, "setregid" }, 1690 /* 204 */ { 0, "install_utrap" }, 1691 /* 205 */ { 0, 0 /* reserved */ }, 1692 /* 206 */ { 0, 0 /* reserved */ }, 1693 /* 207 */ { 0, 0 /* reserved */ }, 1694 /* 208 */ { 0, 0 /* reserved */ }, 1695 /* 209 */ { 0, 0 /* reserved */ }, 1696 /* 210 */ { 0, "signotifywait" }, 1697 /* 211 */ { 0, "lwp_sigredirect" }, 1698 /* 212 */ { 0, "lwp_alarm" }, 1699 }; 1700 1701 static char *(solaris_error_names[]) = { 1702 /* 0 */ "ESUCCESS", 1703 /* 1 */ "EPERM", 1704 /* 2 */ "ENOENT", 1705 /* 3 */ "ESRCH", 1706 /* 4 */ "EINTR", 1707 /* 5 */ "EIO", 1708 /* 6 */ "ENXIO", 1709 /* 7 */ "E2BIG", 1710 /* 8 */ "ENOEXEC", 1711 /* 9 */ "EBADF", 1712 /* 10 */ "ECHILD", 1713 /* 11 */ "EAGAIN", 1714 /* 12 */ "ENOMEM", 1715 /* 13 */ "EACCES", 1716 /* 14 */ "EFAULT", 1717 /* 15 */ "ENOTBLK", 1718 /* 16 */ "EBUSY", 1719 /* 17 */ "EEXIST", 1720 /* 18 */ "EXDEV", 1721 /* 19 */ "ENODEV", 1722 /* 20 */ "ENOTDIR", 1723 /* 21 */ "EISDIR", 1724 /* 22 */ "EINVAL", 1725 /* 23 */ "ENFILE", 1726 /* 24 */ "EMFILE", 1727 /* 25 */ "ENOTTY", 1728 /* 26 */ "ETXTBSY", 1729 /* 27 */ "EFBIG", 1730 /* 28 */ "ENOSPC", 1731 /* 29 */ "ESPIPE", 1732 /* 30 */ "EROFS", 1733 /* 31 */ "EMLINK", 1734 /* 32 */ "EPIPE", 1735 /* 33 */ "EDOM", 1736 /* 34 */ "ERANGE", 1737 /* 35 */ "ENOMSG", 1738 /* 36 */ "EIDRM", 1739 /* 37 */ "ECHRNG", 1740 /* 38 */ "EL2NSYNC", 1741 /* 39 */ "EL3HLT", 1742 /* 40 */ "EL3RST", 1743 /* 41 */ "ELNRNG", 1744 /* 42 */ "EUNATCH", 1745 /* 43 */ "ENOCSI", 1746 /* 44 */ "EL2HLT", 1747 /* 45 */ "EDEADLK", 1748 /* 46 */ "ENOLCK", 1749 /* 47 */ "ECANCELED", 1750 /* 48 */ "ENOTSUP", 1751 /* 49 */ "EDQUOT", 1752 /* 50 */ "EBADE", 1753 /* 51 */ "EBADR", 1754 /* 52 */ "EXFULL", 1755 /* 53 */ "ENOANO", 1756 /* 54 */ "EBADRQC", 1757 /* 55 */ "EBADSLT", 1758 /* 56 */ "EDEADLOCK", 1759 /* 57 */ "EBFONT", 1760 /* 58 */ "Error code 58", 1761 /* 59 */ "Error code 59", 1762 /* 60 */ "ENOSTR", 1763 /* 61 */ "ENODATA", 1764 /* 62 */ "ETIME", 1765 /* 63 */ "ENOSR", 1766 /* 64 */ "ENONET", 1767 /* 65 */ "ENOPKG", 1768 /* 66 */ "EREMOTE", 1769 /* 67 */ "ENOLINK", 1770 /* 68 */ "EADV", 1771 /* 69 */ "ESRMNT", 1772 /* 70 */ "ECOMM", 1773 /* 71 */ "EPROTO", 1774 /* 72 */ "Error code 72", 1775 /* 73 */ "Error code 73", 1776 /* 74 */ "EMULTIHOP", 1777 /* 75 */ "Error code 75", 1778 /* 76 */ "Error code 76", 1779 /* 77 */ "EBADMSG", 1780 /* 78 */ "ENAMETOOLONG", 1781 /* 79 */ "EOVERFLOW", 1782 /* 80 */ "ENOTUNIQ", 1783 /* 81 */ "EBADFD", 1784 /* 82 */ "EREMCHG", 1785 /* 83 */ "ELIBACC", 1786 /* 84 */ "ELIBBAD", 1787 /* 85 */ "ELIBSCN", 1788 /* 86 */ "ELIBMAX", 1789 /* 87 */ "ELIBEXEC", 1790 /* 88 */ "EILSEQ", 1791 /* 89 */ "ENOSYS", 1792 /* 90 */ "ELOOP", 1793 /* 91 */ "ERESTART", 1794 /* 92 */ "ESTRPIPE", 1795 /* 93 */ "ENOTEMPTY", 1796 /* 94 */ "EUSERS", 1797 /* 95 */ "ENOTSOCK", 1798 /* 96 */ "EDESTADDRREQ", 1799 /* 97 */ "EMSGSIZE", 1800 /* 98 */ "EPROTOTYPE", 1801 /* 99 */ "ENOPROTOOPT", 1802 /* 100 */ "Error code 100", 1803 /* 101 */ "Error code 101", 1804 /* 102 */ "Error code 102", 1805 /* 103 */ "Error code 103", 1806 /* 104 */ "Error code 104", 1807 /* 105 */ "Error code 105", 1808 /* 106 */ "Error code 106", 1809 /* 107 */ "Error code 107", 1810 /* 108 */ "Error code 108", 1811 /* 109 */ "Error code 109", 1812 /* 110 */ "Error code 110", 1813 /* 111 */ "Error code 111", 1814 /* 112 */ "Error code 112", 1815 /* 113 */ "Error code 113", 1816 /* 114 */ "Error code 114", 1817 /* 115 */ "Error code 115", 1818 /* 116 */ "Error code 116", 1819 /* 117 */ "Error code 117", 1820 /* 118 */ "Error code 118", 1821 /* 119 */ "Error code 119", 1822 /* 120 */ "EPROTONOSUPPORT", 1823 /* 121 */ "ESOCKTNOSUPPORT", 1824 /* 122 */ "EOPNOTSUPP", 1825 /* 123 */ "EPFNOSUPPORT", 1826 /* 124 */ "EAFNOSUPPORT", 1827 /* 125 */ "EADDRINUSE", 1828 /* 126 */ "EADDRNOTAVAIL", 1829 /* 127 */ "ENETDOWN", 1830 /* 128 */ "ENETUNREACH", 1831 /* 129 */ "ENETRESET", 1832 /* 130 */ "ECONNABORTED", 1833 /* 131 */ "ECONNRESET", 1834 /* 132 */ "ENOBUFS", 1835 /* 133 */ "EISCONN", 1836 /* 134 */ "ENOTCONN", 1837 /* 135 */ "Error code 135", /* XENIX has 135 - 142 */ 1838 /* 136 */ "Error code 136", 1839 /* 137 */ "Error code 137", 1840 /* 138 */ "Error code 138", 1841 /* 139 */ "Error code 139", 1842 /* 140 */ "Error code 140", 1843 /* 141 */ "Error code 141", 1844 /* 142 */ "Error code 142", 1845 /* 143 */ "ESHUTDOWN", 1846 /* 144 */ "ETOOMANYREFS", 1847 /* 145 */ "ETIMEDOUT", 1848 /* 146 */ "ECONNREFUSED", 1849 /* 147 */ "EHOSTDOWN", 1850 /* 148 */ "EHOSTUNREACH", 1851 /* 149 */ "EALREADY", 1852 /* 150 */ "EINPROGRESS", 1853 /* 151 */ "ESTALE", 1854 }; 1855 1856 static char *(solaris_signal_names[]) = { 1857 /* 0 */ 0, 1858 /* 1 */ "SIGHUP", 1859 /* 2 */ "SIGINT", 1860 /* 3 */ "SIGQUIT", 1861 /* 4 */ "SIGILL", 1862 /* 5 */ "SIGTRAP", 1863 /* 6 */ "SIGABRT", 1864 /* 7 */ "SIGEMT", 1865 /* 8 */ "SIGFPE", 1866 /* 9 */ "SIGKILL", 1867 /* 10 */ "SIGBUS", 1868 /* 11 */ "SIGSEGV", 1869 /* 12 */ "SIGSYS", 1870 /* 13 */ "SIGPIPE", 1871 /* 14 */ "SIGALRM", 1872 /* 15 */ "SIGTERM", 1873 /* 16 */ "SIGUSR1", 1874 /* 17 */ "SIGUSR2", 1875 /* 18 */ "SIGCHLD", 1876 /* 19 */ "SIGPWR", 1877 /* 20 */ "SIGWINCH", 1878 /* 21 */ "SIGURG", 1879 /* 22 */ "SIGPOLL", 1880 /* 23 */ "SIGSTOP", 1881 /* 24 */ "SIGTSTP", 1882 /* 25 */ "SIGCONT", 1883 /* 26 */ "SIGTTIN", 1884 /* 27 */ "SIGTTOU", 1885 /* 28 */ "SIGVTALRM", 1886 /* 29 */ "SIGPROF", 1887 /* 30 */ "SIGXCPU", 1888 /* 31 */ "SIGXFSZ", 1889 /* 32 */ "SIGWAITING", 1890 /* 33 */ "SIGLWP", 1891 /* 34 */ "SIGFREEZE", 1892 /* 35 */ "SIGTHAW", 1893 /* 36 */ "SIGCANCEL", 1894 }; 1895 1896 static emul_syscall emul_solaris_syscalls = { 1897 solaris_descriptors, 1898 sizeof(solaris_descriptors) / sizeof(solaris_descriptors[0]), 1899 solaris_error_names, 1900 sizeof(solaris_error_names) / sizeof(solaris_error_names[0]), 1901 solaris_signal_names, 1902 sizeof(solaris_signal_names) / sizeof(solaris_signal_names[0]), 1903 }; 1904 1905 1906 /* Solaris's os_emul interface, most are just passed on to the generic 1907 syscall stuff */ 1908 1909 static os_emul_data * 1910 emul_solaris_create(device *root, 1911 bfd *image, 1912 const char *name) 1913 { 1914 /* check that this emulation is really for us */ 1915 if (name != NULL && strcmp(name, "solaris") != 0) 1916 return NULL; 1917 1918 if (image == NULL) 1919 return NULL; 1920 1921 return emul_unix_create(root, image, "solaris", &emul_solaris_syscalls); 1922 } 1923 1924 static void 1925 emul_solaris_init(os_emul_data *emul_data, 1926 int nr_cpus) 1927 { 1928 /* nothing yet */ 1929 } 1930 1931 static void 1932 emul_solaris_system_call(cpu *processor, 1933 unsigned_word cia, 1934 os_emul_data *emul_data) 1935 { 1936 emul_do_system_call(emul_data, 1937 emul_data->syscalls, 1938 cpu_registers(processor)->gpr[0], 1939 3, /*r3 contains arg0*/ 1940 processor, 1941 cia); 1942 } 1943 1944 const os_emul emul_solaris = { 1945 "solaris", 1946 emul_solaris_create, 1947 emul_solaris_init, 1948 emul_solaris_system_call, 1949 0, /*instruction_call*/ 1950 0 /*data*/ 1951 }; 1952 1953 1954 /* EMULATION 1955 1956 Linux - Emulation of user programs for Linux/PPC 1957 1958 DESCRIPTION 1959 1960 */ 1961 1962 1963 /* Linux specific implementation */ 1964 1965 typedef unsigned32 linux_dev_t; 1966 typedef unsigned32 linux_ino_t; 1967 typedef unsigned32 linux_mode_t; 1968 typedef unsigned16 linux_nlink_t; 1969 typedef signed32 linux_off_t; 1970 typedef signed32 linux_pid_t; 1971 typedef unsigned32 linux_uid_t; 1972 typedef unsigned32 linux_gid_t; 1973 typedef unsigned32 linux_size_t; 1974 typedef signed32 linux_ssize_t; 1975 typedef signed32 linux_ptrdiff_t; 1976 typedef signed32 linux_time_t; 1977 typedef signed32 linux_clock_t; 1978 typedef signed32 linux_daddr_t; 1979 1980 #ifdef HAVE_SYS_STAT_H 1981 /* For the PowerPC, don't both with the 'old' stat structure, since there 1982 should be no extant binaries with that structure. */ 1983 1984 struct linux_stat { 1985 linux_dev_t st_dev; 1986 linux_ino_t st_ino; 1987 linux_mode_t st_mode; 1988 linux_nlink_t st_nlink; 1989 linux_uid_t st_uid; 1990 linux_gid_t st_gid; 1991 linux_dev_t st_rdev; 1992 linux_off_t st_size; 1993 unsigned32 st_blksize; 1994 unsigned32 st_blocks; 1995 unsigned32 st_atimx; /* don't use st_{a,c,m}time, that might a macro */ 1996 unsigned32 __unused1; /* defined by the host's stat.h */ 1997 unsigned32 st_mtimx; 1998 unsigned32 __unused2; 1999 unsigned32 st_ctimx; 2000 unsigned32 __unused3; 2001 unsigned32 __unused4; 2002 unsigned32 __unused5; 2003 }; 2004 2005 /* Convert from host stat structure to solaris stat structure */ 2006 STATIC_INLINE_EMUL_UNIX void 2007 convert_to_linux_stat(unsigned_word addr, 2008 struct stat *host, 2009 cpu *processor, 2010 unsigned_word cia) 2011 { 2012 struct linux_stat target; 2013 2014 target.st_dev = H2T_4(host->st_dev); 2015 target.st_ino = H2T_4(host->st_ino); 2016 target.st_mode = H2T_4(host->st_mode); 2017 target.st_nlink = H2T_2(host->st_nlink); 2018 target.st_uid = H2T_4(host->st_uid); 2019 target.st_gid = H2T_4(host->st_gid); 2020 target.st_size = H2T_4(host->st_size); 2021 2022 #ifdef HAVE_ST_RDEV 2023 target.st_rdev = H2T_4(host->st_rdev); 2024 #else 2025 target.st_rdev = 0; 2026 #endif 2027 2028 #ifdef HAVE_ST_BLKSIZE 2029 target.st_blksize = H2T_4(host->st_blksize); 2030 #else 2031 target.st_blksize = 0; 2032 #endif 2033 2034 #ifdef HAVE_ST_BLOCKS 2035 target.st_blocks = H2T_4(host->st_blocks); 2036 #else 2037 target.st_blocks = 0; 2038 #endif 2039 2040 target.st_atimx = H2T_4(host->st_atime); 2041 target.st_ctimx = H2T_4(host->st_ctime); 2042 target.st_mtimx = H2T_4(host->st_mtime); 2043 target.__unused1 = 0; 2044 target.__unused2 = 0; 2045 target.__unused3 = 0; 2046 target.__unused4 = 0; 2047 target.__unused5 = 0; 2048 2049 emul_write_buffer(&target, addr, sizeof(target), processor, cia); 2050 } 2051 #endif /* HAVE_SYS_STAT_H */ 2052 2053 #ifndef HAVE_STAT 2054 #define do_linux_stat 0 2055 #else 2056 static void 2057 do_linux_stat(os_emul_data *emul, 2058 unsigned call, 2059 const int arg0, 2060 cpu *processor, 2061 unsigned_word cia) 2062 { 2063 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 2064 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; 2065 char path_buf[PATH_MAX]; 2066 struct stat buf; 2067 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 2068 int status; 2069 2070 if (WITH_TRACE && ppc_trace[trace_os_emul]) 2071 printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt); 2072 2073 status = stat (path, &buf); 2074 if (status == 0) 2075 convert_to_linux_stat (stat_pkt, &buf, processor, cia); 2076 2077 emul_write_status(processor, status, errno); 2078 } 2079 #endif 2080 2081 #ifndef HAVE_LSTAT 2082 #define do_linux_lstat 0 2083 #else 2084 static void 2085 do_linux_lstat(os_emul_data *emul, 2086 unsigned call, 2087 const int arg0, 2088 cpu *processor, 2089 unsigned_word cia) 2090 { 2091 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; 2092 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; 2093 char path_buf[PATH_MAX]; 2094 struct stat buf; 2095 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); 2096 int status; 2097 2098 if (WITH_TRACE && ppc_trace[trace_os_emul]) 2099 printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt); 2100 2101 status = lstat (path, &buf); 2102 if (status == 0) 2103 convert_to_linux_stat (stat_pkt, &buf, processor, cia); 2104 2105 emul_write_status(processor, status, errno); 2106 } 2107 #endif 2108 2109 #ifndef HAVE_FSTAT 2110 #define do_linux_fstat 0 2111 #else 2112 static void 2113 do_linux_fstat(os_emul_data *emul, 2114 unsigned call, 2115 const int arg0, 2116 cpu *processor, 2117 unsigned_word cia) 2118 { 2119 int fildes = (int)cpu_registers(processor)->gpr[arg0]; 2120 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; 2121 struct stat buf; 2122 int status; 2123 2124 if (WITH_TRACE && ppc_trace[trace_os_emul]) 2125 printf_filtered ("%d, 0x%lx", fildes, (long)stat_pkt); 2126 2127 status = fstat (fildes, &buf); 2128 if (status == 0) 2129 convert_to_linux_stat (stat_pkt, &buf, processor, cia); 2130 2131 emul_write_status(processor, status, errno); 2132 } 2133 #endif 2134 2135 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE) 2136 #define LINUX_NCC 10 2137 #define LINUX_NCCS 19 2138 2139 #define LINUX_VINTR 0 2140 #define LINUX_VQUIT 1 2141 #define LINUX_VERASE 2 2142 #define LINUX_VKILL 3 2143 #define LINUX_VEOF 4 2144 #define LINUX_VMIN 5 2145 #define LINUX_VEOL 6 2146 #define LINUX_VTIME 7 2147 #define LINUX_VEOL2 8 2148 #define LINUX_VSWTC 9 2149 #define LINUX_VWERASE 10 2150 #define LINUX_VREPRINT 11 2151 #define LINUX_VSUSP 12 2152 #define LINUX_VSTART 13 2153 #define LINUX_VSTOP 14 2154 #define LINUX_VLNEXT 15 2155 #define LINUX_VDISCARD 16 2156 2157 #define LINUX_IOC_NRBITS 8 2158 #define LINUX_IOC_TYPEBITS 8 2159 #define LINUX_IOC_SIZEBITS 13 2160 #define LINUX_IOC_DIRBITS 3 2161 2162 #define LINUX_IOC_NRMASK ((1 << LINUX_IOC_NRBITS)-1) 2163 #define LINUX_IOC_TYPEMASK ((1 << LINUX_IOC_TYPEBITS)-1) 2164 #define LINUX_IOC_SIZEMASK ((1 << LINUX_IOC_SIZEBITS)-1) 2165 #define LINUX_IOC_DIRMASK ((1 << LINUX_IOC_DIRBITS)-1) 2166 2167 #define LINUX_IOC_NRSHIFT 0 2168 #define LINUX_IOC_TYPESHIFT (LINUX_IOC_NRSHIFT+LINUX_IOC_NRBITS) 2169 #define LINUX_IOC_SIZESHIFT (LINUX_IOC_TYPESHIFT+LINUX_IOC_TYPEBITS) 2170 #define LINUX_IOC_DIRSHIFT (LINUX_IOC_SIZESHIFT+LINUX_IOC_SIZEBITS) 2171 2172 /* 2173 * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. 2174 * And this turns out useful to catch old ioctl numbers in header 2175 * files for us. 2176 */ 2177 #define LINUX_IOC_NONE 1U 2178 #define LINUX_IOC_READ 2U 2179 #define LINUX_IOC_WRITE 4U 2180 2181 #define LINUX_IOC(dir,type,nr,size) \ 2182 (((dir) << LINUX_IOC_DIRSHIFT) | \ 2183 ((type) << LINUX_IOC_TYPESHIFT) | \ 2184 ((nr) << LINUX_IOC_NRSHIFT) | \ 2185 ((size) << LINUX_IOC_SIZESHIFT)) 2186 2187 /* used to create numbers */ 2188 #define LINUX_IO(type,nr) LINUX_IOC(LINUX_IOC_NONE,(type),(nr),0) 2189 #define LINUX_IOR(type,nr,size) LINUX_IOC(LINUX_IOC_READ,(type),(nr),sizeof(size)) 2190 #define LINUX_IOW(type,nr,size) LINUX_IOC(LINUX_IOC_WRITE,(type),(nr),sizeof(size)) 2191 #define LINUX_IOWR(type,nr,size) LINUX_IOC(LINUX_IOC_READ|LINUX_IOC_WRITE,(type),(nr),sizeof(size)) 2192 #endif 2193 2194 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE) 2195 /* Convert to/from host termio structure */ 2196 2197 struct linux_termio { 2198 unsigned16 c_iflag; /* input modes */ 2199 unsigned16 c_oflag; /* output modes */ 2200 unsigned16 c_cflag; /* control modes */ 2201 unsigned16 c_lflag; /* line discipline modes */ 2202 unsigned8 c_line; /* line discipline */ 2203 unsigned8 c_cc[LINUX_NCC]; /* control chars */ 2204 }; 2205 2206 STATIC_INLINE_EMUL_UNIX void 2207 convert_to_linux_termio(unsigned_word addr, 2208 struct termio *host, 2209 cpu *processor, 2210 unsigned_word cia) 2211 { 2212 struct linux_termio target; 2213 int i; 2214 2215 target.c_iflag = H2T_2 (host->c_iflag); 2216 target.c_oflag = H2T_2 (host->c_oflag); 2217 target.c_cflag = H2T_2 (host->c_cflag); 2218 target.c_lflag = H2T_2 (host->c_lflag); 2219 2220 #if defined(HAVE_TERMIO_CLINE) || defined(HAVE_TERMIOS_CLINE) 2221 target.c_line = host->c_line; 2222 #else 2223 target.c_line = 0; 2224 #endif 2225 2226 for (i = 0; i < LINUX_NCC; i++) 2227 target.c_cc[i] = 0; 2228 2229 #ifdef VINTR 2230 target.c_cc[LINUX_VINTR] = host->c_cc[VINTR]; 2231 #endif 2232 2233 #ifdef VQUIT 2234 target.c_cc[LINUX_VQUIT] = host->c_cc[VQUIT]; 2235 #endif 2236 2237 #ifdef VERASE 2238 target.c_cc[LINUX_VERASE] = host->c_cc[VERASE]; 2239 #endif 2240 2241 #ifdef VKILL 2242 target.c_cc[LINUX_VKILL] = host->c_cc[VKILL]; 2243 #endif 2244 2245 #ifdef VEOF 2246 target.c_cc[LINUX_VEOF] = host->c_cc[VEOF]; 2247 #endif 2248 2249 #ifdef VMIN 2250 target.c_cc[LINUX_VMIN] = host->c_cc[VMIN]; 2251 #endif 2252 2253 #ifdef VEOL 2254 target.c_cc[LINUX_VEOL] = host->c_cc[VEOL]; 2255 #endif 2256 2257 #ifdef VTIME 2258 target.c_cc[LINUX_VTIME] = host->c_cc[VTIME]; 2259 #endif 2260 2261 #ifdef VEOL2 2262 target.c_cc[LINUX_VEOL2] = host->c_cc[VEOL2]; 2263 #endif 2264 2265 #ifdef VSWTC 2266 target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTC]; 2267 #endif 2268 2269 #ifdef VSWTCH 2270 target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTCH]; 2271 #endif 2272 2273 emul_write_buffer(&target, addr, sizeof(target), processor, cia); 2274 } 2275 #endif /* HAVE_TERMIO_STRUCTURE */ 2276 2277 #ifdef HAVE_TERMIOS_STRUCTURE 2278 /* Convert to/from host termios structure */ 2279 2280 typedef unsigned32 linux_tcflag_t; 2281 typedef unsigned8 linux_cc_t; 2282 typedef unsigned32 linux_speed_t; 2283 2284 struct linux_termios { 2285 linux_tcflag_t c_iflag; 2286 linux_tcflag_t c_oflag; 2287 linux_tcflag_t c_cflag; 2288 linux_tcflag_t c_lflag; 2289 linux_cc_t c_cc[LINUX_NCCS]; 2290 linux_cc_t c_line; 2291 signed32 c_ispeed; 2292 signed32 c_ospeed; 2293 }; 2294 2295 STATIC_INLINE_EMUL_UNIX void 2296 convert_to_linux_termios(unsigned_word addr, 2297 struct termios *host, 2298 cpu *processor, 2299 unsigned_word cia) 2300 { 2301 struct linux_termios target; 2302 int i; 2303 2304 target.c_iflag = H2T_4 (host->c_iflag); 2305 target.c_oflag = H2T_4 (host->c_oflag); 2306 target.c_cflag = H2T_4 (host->c_cflag); 2307 target.c_lflag = H2T_4 (host->c_lflag); 2308 2309 for (i = 0; i < LINUX_NCCS; i++) 2310 target.c_cc[i] = 0; 2311 2312 #ifdef VINTR 2313 target.c_cc[LINUX_VINTR] = host->c_cc[VINTR]; 2314 #endif 2315 2316 #ifdef VQUIT 2317 target.c_cc[LINUX_VQUIT] = host->c_cc[VQUIT]; 2318 #endif 2319 2320 #ifdef VERASE 2321 target.c_cc[LINUX_VERASE] = host->c_cc[VERASE]; 2322 #endif 2323 2324 #ifdef VKILL 2325 target.c_cc[LINUX_VKILL] = host->c_cc[VKILL]; 2326 #endif 2327 2328 #ifdef VEOF 2329 target.c_cc[LINUX_VEOF] = host->c_cc[VEOF]; 2330 #endif 2331 2332 #ifdef VEOL 2333 target.c_cc[LINUX_VEOL] = host->c_cc[VEOL]; 2334 #endif 2335 2336 #ifdef VEOL2 2337 target.c_cc[LINUX_VEOL2] = host->c_cc[VEOL2]; 2338 #endif 2339 2340 #ifdef VSWTCH 2341 target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTCH]; 2342 #endif 2343 2344 #ifdef HAVE_TERMIOS_CLINE 2345 target.c_line = host->c_line; 2346 #else 2347 target.c_line = 0; 2348 #endif 2349 2350 #ifdef HAVE_CFGETISPEED 2351 target.c_ispeed = cfgetispeed (host); 2352 #else 2353 target.c_ispeed = 0; 2354 #endif 2355 2356 #ifdef HAVE_CFGETOSPEED 2357 target.c_ospeed = cfgetospeed (host); 2358 #else 2359 target.c_ospeed = 0; 2360 #endif 2361 2362 emul_write_buffer(&target, addr, sizeof(target), processor, cia); 2363 } 2364 #endif /* HAVE_TERMIOS_STRUCTURE */ 2365 2366 #ifndef HAVE_IOCTL 2367 #define do_linux_ioctl 0 2368 #else 2369 static void 2370 do_linux_ioctl(os_emul_data *emul, 2371 unsigned call, 2372 const int arg0, 2373 cpu *processor, 2374 unsigned_word cia) 2375 { 2376 int fildes = cpu_registers(processor)->gpr[arg0]; 2377 unsigned request = cpu_registers(processor)->gpr[arg0+1]; 2378 unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2]; 2379 int status = 0; 2380 const char *name = "<unknown>"; 2381 2382 #ifdef HAVE_TERMIOS_STRUCTURE 2383 struct termios host_termio; 2384 2385 #else 2386 #ifdef HAVE_TERMIO_STRUCTURE 2387 struct termio host_termio; 2388 #endif 2389 #endif 2390 2391 switch (request) 2392 { 2393 case 0: /* make sure we have at least one case */ 2394 default: 2395 status = -1; 2396 errno = EINVAL; 2397 break; 2398 2399 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE) 2400 #if defined(TCGETA) || defined(TCGETS) || defined(HAVE_TCGETATTR) 2401 case LINUX_IOR('t', 23, struct linux_termio): /* TCGETA */ 2402 name = "TCGETA"; 2403 #ifdef HAVE_TCGETATTR 2404 status = tcgetattr(fildes, &host_termio); 2405 #elif defined(TCGETS) 2406 status = ioctl (fildes, TCGETS, &host_termio); 2407 #else 2408 status = ioctl (fildes, TCGETA, &host_termio); 2409 #endif 2410 if (status == 0) 2411 convert_to_linux_termio (argp_addr, &host_termio, processor, cia); 2412 break; 2413 #endif /* TCGETA */ 2414 #endif /* HAVE_TERMIO_STRUCTURE */ 2415 2416 #ifdef HAVE_TERMIOS_STRUCTURE 2417 #if defined(TCGETS) || defined(HAVE_TCGETATTR) 2418 case LINUX_IOR('t', 19, struct linux_termios): /* TCGETS */ 2419 name = "TCGETS"; 2420 #ifdef HAVE_TCGETATTR 2421 status = tcgetattr(fildes, &host_termio); 2422 #else 2423 status = ioctl (fildes, TCGETS, &host_termio); 2424 #endif 2425 if (status == 0) 2426 convert_to_linux_termios (argp_addr, &host_termio, processor, cia); 2427 break; 2428 #endif /* TCGETS */ 2429 #endif /* HAVE_TERMIOS_STRUCTURE */ 2430 } 2431 2432 emul_write_status(processor, status, errno); 2433 2434 if (WITH_TRACE && ppc_trace[trace_os_emul]) 2435 printf_filtered ("%d, 0x%x [%s], 0x%lx", fildes, request, name, (long)argp_addr); 2436 } 2437 #endif /* HAVE_IOCTL */ 2438 2439 static emul_syscall_descriptor linux_descriptors[] = { 2440 /* 0 */ { 0, "setup" }, 2441 /* 1 */ { do_unix_exit, "exit" }, 2442 /* 2 */ { 0, "fork" }, 2443 /* 3 */ { do_unix_read, "read" }, 2444 /* 4 */ { do_unix_write, "write" }, 2445 /* 5 */ { do_unix_open, "open" }, 2446 /* 6 */ { do_unix_close, "close" }, 2447 /* 7 */ { 0, "waitpid" }, 2448 /* 8 */ { 0, "creat" }, 2449 /* 9 */ { do_unix_link, "link" }, 2450 /* 10 */ { do_unix_unlink, "unlink" }, 2451 /* 11 */ { 0, "execve" }, 2452 /* 12 */ { do_unix_chdir, "chdir" }, 2453 /* 13 */ { do_unix_time, "time" }, 2454 /* 14 */ { 0, "mknod" }, 2455 /* 15 */ { 0, "chmod" }, 2456 /* 16 */ { 0, "chown" }, 2457 /* 17 */ { 0, "break" }, 2458 /* 18 */ { 0, "stat" }, 2459 /* 19 */ { do_unix_lseek, "lseek" }, 2460 /* 20 */ { do_unix_getpid, "getpid" }, 2461 /* 21 */ { 0, "mount" }, 2462 /* 22 */ { 0, "umount" }, 2463 /* 23 */ { 0, "setuid" }, 2464 /* 24 */ { do_unix_getuid, "getuid" }, 2465 /* 25 */ { 0, "stime" }, 2466 /* 26 */ { 0, "ptrace" }, 2467 /* 27 */ { 0, "alarm" }, 2468 /* 28 */ { 0, "fstat" }, 2469 /* 29 */ { 0, "pause" }, 2470 /* 30 */ { 0, "utime" }, 2471 /* 31 */ { 0, "stty" }, 2472 /* 32 */ { 0, "gtty" }, 2473 /* 33 */ { do_unix_access, "access" }, 2474 /* 34 */ { 0, "nice" }, 2475 /* 35 */ { 0, "ftime" }, 2476 /* 36 */ { 0, "sync" }, 2477 /* 37 */ { 0, "kill" }, 2478 /* 38 */ { 0, "rename" }, 2479 /* 39 */ { do_unix_mkdir, "mkdir" }, 2480 /* 40 */ { do_unix_rmdir, "rmdir" }, 2481 /* 41 */ { do_unix_dup, "dup" }, 2482 /* 42 */ { 0, "pipe" }, 2483 /* 43 */ { 0, "times" }, 2484 /* 44 */ { 0, "prof" }, 2485 /* 45 */ { do_unix_break, "brk" }, 2486 /* 46 */ { 0, "setgid" }, 2487 /* 47 */ { do_unix_getgid, "getgid" }, 2488 /* 48 */ { 0, "signal" }, 2489 /* 49 */ { do_unix_geteuid, "geteuid" }, 2490 /* 50 */ { do_unix_getegid, "getegid" }, 2491 /* 51 */ { 0, "acct" }, 2492 /* 52 */ { 0, "phys" }, 2493 /* 53 */ { 0, "lock" }, 2494 /* 54 */ { do_linux_ioctl, "ioctl" }, 2495 /* 55 */ { 0, "fcntl" }, 2496 /* 56 */ { 0, "mpx" }, 2497 /* 57 */ { 0, "setpgid" }, 2498 /* 58 */ { 0, "ulimit" }, 2499 /* 59 */ { 0, "olduname" }, 2500 /* 60 */ { do_unix_umask, "umask" }, 2501 /* 61 */ { 0, "chroot" }, 2502 /* 62 */ { 0, "ustat" }, 2503 /* 63 */ { do_unix_dup2, "dup2" }, 2504 /* 64 */ { do_unix_getppid, "getppid" }, 2505 /* 65 */ { 0, "getpgrp" }, 2506 /* 66 */ { 0, "setsid" }, 2507 /* 67 */ { 0, "sigaction" }, 2508 /* 68 */ { 0, "sgetmask" }, 2509 /* 69 */ { 0, "ssetmask" }, 2510 /* 70 */ { 0, "setreuid" }, 2511 /* 71 */ { 0, "setregid" }, 2512 /* 72 */ { 0, "sigsuspend" }, 2513 /* 73 */ { 0, "sigpending" }, 2514 /* 74 */ { 0, "sethostname" }, 2515 /* 75 */ { 0, "setrlimit" }, 2516 /* 76 */ { 0, "getrlimit" }, 2517 /* 77 */ { do_unix_getrusage, "getrusage" }, 2518 /* 78 */ { do_unix_gettimeofday, "gettimeofday" }, 2519 /* 79 */ { 0, "settimeofday" }, 2520 /* 80 */ { 0, "getgroups" }, 2521 /* 81 */ { 0, "setgroups" }, 2522 /* 82 */ { 0, "select" }, 2523 /* 83 */ { do_unix_symlink, "symlink" }, 2524 /* 84 */ { 0, "lstat" }, 2525 /* 85 */ { 0, "readlink" }, 2526 /* 86 */ { 0, "uselib" }, 2527 /* 87 */ { 0, "swapon" }, 2528 /* 88 */ { 0, "reboot" }, 2529 /* 89 */ { 0, "readdir" }, 2530 /* 90 */ { 0, "mmap" }, 2531 /* 91 */ { 0, "munmap" }, 2532 /* 92 */ { 0, "truncate" }, 2533 /* 93 */ { 0, "ftruncate" }, 2534 /* 94 */ { 0, "fchmod" }, 2535 /* 95 */ { 0, "fchown" }, 2536 /* 96 */ { 0, "getpriority" }, 2537 /* 97 */ { 0, "setpriority" }, 2538 /* 98 */ { 0, "profil" }, 2539 /* 99 */ { 0, "statfs" }, 2540 /* 100 */ { 0, "fstatfs" }, 2541 /* 101 */ { 0, "ioperm" }, 2542 /* 102 */ { 0, "socketcall" }, 2543 /* 103 */ { 0, "syslog" }, 2544 /* 104 */ { 0, "setitimer" }, 2545 /* 105 */ { 0, "getitimer" }, 2546 /* 106 */ { do_linux_stat, "newstat" }, 2547 /* 107 */ { do_linux_lstat, "newlstat" }, 2548 /* 108 */ { do_linux_fstat, "newfstat" }, 2549 /* 109 */ { 0, "uname" }, 2550 /* 110 */ { 0, "iopl" }, 2551 /* 111 */ { 0, "vhangup" }, 2552 /* 112 */ { 0, "idle" }, 2553 /* 113 */ { 0, "vm86" }, 2554 /* 114 */ { 0, "wait4" }, 2555 /* 115 */ { 0, "swapoff" }, 2556 /* 116 */ { 0, "sysinfo" }, 2557 /* 117 */ { 0, "ipc" }, 2558 /* 118 */ { 0, "fsync" }, 2559 /* 119 */ { 0, "sigreturn" }, 2560 /* 120 */ { 0, "clone" }, 2561 /* 121 */ { 0, "setdomainname" }, 2562 /* 122 */ { 0, "newuname" }, 2563 /* 123 */ { 0, "modify_ldt" }, 2564 /* 124 */ { 0, "adjtimex" }, 2565 /* 125 */ { 0, "mprotect" }, 2566 /* 126 */ { 0, "sigprocmask" }, 2567 /* 127 */ { 0, "create_module" }, 2568 /* 128 */ { 0, "init_module" }, 2569 /* 129 */ { 0, "delete_module" }, 2570 /* 130 */ { 0, "get_kernel_syms" }, 2571 /* 131 */ { 0, "quotactl" }, 2572 /* 132 */ { 0, "getpgid" }, 2573 /* 133 */ { 0, "fchdir" }, 2574 /* 134 */ { 0, "bdflush" }, 2575 /* 135 */ { 0, "sysfs" }, 2576 /* 136 */ { 0, "personality" }, 2577 /* 137 */ { 0, "afs_syscall" }, 2578 /* 138 */ { 0, "setfsuid" }, 2579 /* 139 */ { 0, "setfsgid" }, 2580 /* 140 */ { 0, "llseek" }, 2581 /* 141 */ { 0, "getdents" }, 2582 /* 142 */ { 0, "newselect" }, 2583 /* 143 */ { 0, "flock" }, 2584 /* 144 */ { 0, "msync" }, 2585 /* 145 */ { 0, "readv" }, 2586 /* 146 */ { 0, "writev" }, 2587 /* 147 */ { 0, "getsid" }, 2588 /* 148 */ { 0, "fdatasync" }, 2589 /* 149 */ { 0, "sysctl" }, 2590 /* 150 */ { 0, "mlock" }, 2591 /* 151 */ { 0, "munlock" }, 2592 /* 152 */ { 0, "mlockall" }, 2593 /* 153 */ { 0, "munlockall" }, 2594 /* 154 */ { 0, "sched_setparam" }, 2595 /* 155 */ { 0, "sched_getparam" }, 2596 /* 156 */ { 0, "sched_setscheduler" }, 2597 /* 157 */ { 0, "sched_getscheduler" }, 2598 /* 158 */ { 0, "sched_yield" }, 2599 /* 159 */ { 0, "sched_get_priority_max" }, 2600 /* 160 */ { 0, "sched_get_priority_min" }, 2601 /* 161 */ { 0, "sched_rr_get_interval" }, 2602 }; 2603 2604 static char *(linux_error_names[]) = { 2605 /* 0 */ "ESUCCESS", 2606 /* 1 */ "EPERM", 2607 /* 2 */ "ENOENT", 2608 /* 3 */ "ESRCH", 2609 /* 4 */ "EINTR", 2610 /* 5 */ "EIO", 2611 /* 6 */ "ENXIO", 2612 /* 7 */ "E2BIG", 2613 /* 8 */ "ENOEXEC", 2614 /* 9 */ "EBADF", 2615 /* 10 */ "ECHILD", 2616 /* 11 */ "EAGAIN", 2617 /* 12 */ "ENOMEM", 2618 /* 13 */ "EACCES", 2619 /* 14 */ "EFAULT", 2620 /* 15 */ "ENOTBLK", 2621 /* 16 */ "EBUSY", 2622 /* 17 */ "EEXIST", 2623 /* 18 */ "EXDEV", 2624 /* 19 */ "ENODEV", 2625 /* 20 */ "ENOTDIR", 2626 /* 21 */ "EISDIR", 2627 /* 22 */ "EINVAL", 2628 /* 23 */ "ENFILE", 2629 /* 24 */ "EMFILE", 2630 /* 25 */ "ENOTTY", 2631 /* 26 */ "ETXTBSY", 2632 /* 27 */ "EFBIG", 2633 /* 28 */ "ENOSPC", 2634 /* 29 */ "ESPIPE", 2635 /* 30 */ "EROFS", 2636 /* 31 */ "EMLINK", 2637 /* 32 */ "EPIPE", 2638 /* 33 */ "EDOM", 2639 /* 34 */ "ERANGE", 2640 /* 35 */ "EDEADLK", 2641 /* 36 */ "ENAMETOOLONG", 2642 /* 37 */ "ENOLCK", 2643 /* 38 */ "ENOSYS", 2644 /* 39 */ "ENOTEMPTY", 2645 /* 40 */ "ELOOP", 2646 /* 41 */ 0, 2647 /* 42 */ "ENOMSG", 2648 /* 43 */ "EIDRM", 2649 /* 44 */ "ECHRNG", 2650 /* 45 */ "EL2NSYNC", 2651 /* 46 */ "EL3HLT", 2652 /* 47 */ "EL3RST", 2653 /* 48 */ "ELNRNG", 2654 /* 49 */ "EUNATCH", 2655 /* 50 */ "ENOCSI", 2656 /* 51 */ "EL2HLT", 2657 /* 52 */ "EBADE", 2658 /* 53 */ "EBADR", 2659 /* 54 */ "EXFULL", 2660 /* 55 */ "ENOANO", 2661 /* 56 */ "EBADRQC", 2662 /* 57 */ "EBADSLT", 2663 /* 58 */ "EDEADLOCK", 2664 /* 59 */ "EBFONT", 2665 /* 60 */ "ENOSTR", 2666 /* 61 */ "ENODATA", 2667 /* 62 */ "ETIME", 2668 /* 63 */ "ENOSR", 2669 /* 64 */ "ENONET", 2670 /* 65 */ "ENOPKG", 2671 /* 66 */ "EREMOTE", 2672 /* 67 */ "ENOLINK", 2673 /* 68 */ "EADV", 2674 /* 69 */ "ESRMNT", 2675 /* 70 */ "ECOMM", 2676 /* 71 */ "EPROTO", 2677 /* 72 */ "EMULTIHOP", 2678 /* 73 */ "EDOTDOT", 2679 /* 74 */ "EBADMSG", 2680 /* 75 */ "EOVERFLOW", 2681 /* 76 */ "ENOTUNIQ", 2682 /* 77 */ "EBADFD", 2683 /* 78 */ "EREMCHG", 2684 /* 79 */ "ELIBACC", 2685 /* 80 */ "ELIBBAD", 2686 /* 81 */ "ELIBSCN", 2687 /* 82 */ "ELIBMAX", 2688 /* 83 */ "ELIBEXEC", 2689 /* 84 */ "EILSEQ", 2690 /* 85 */ "ERESTART", 2691 /* 86 */ "ESTRPIPE", 2692 /* 87 */ "EUSERS", 2693 /* 88 */ "ENOTSOCK", 2694 /* 89 */ "EDESTADDRREQ", 2695 /* 90 */ "EMSGSIZE", 2696 /* 91 */ "EPROTOTYPE", 2697 /* 92 */ "ENOPROTOOPT", 2698 /* 93 */ "EPROTONOSUPPORT", 2699 /* 94 */ "ESOCKTNOSUPPORT", 2700 /* 95 */ "EOPNOTSUPP", 2701 /* 96 */ "EPFNOSUPPORT", 2702 /* 97 */ "EAFNOSUPPORT", 2703 /* 98 */ "EADDRINUSE", 2704 /* 99 */ "EADDRNOTAVAIL", 2705 /* 100 */ "ENETDOWN", 2706 /* 101 */ "ENETUNREACH", 2707 /* 102 */ "ENETRESET", 2708 /* 103 */ "ECONNABORTED", 2709 /* 104 */ "ECONNRESET", 2710 /* 105 */ "ENOBUFS", 2711 /* 106 */ "EISCONN", 2712 /* 107 */ "ENOTCONN", 2713 /* 108 */ "ESHUTDOWN", 2714 /* 109 */ "ETOOMANYREFS", 2715 /* 110 */ "ETIMEDOUT", 2716 /* 111 */ "ECONNREFUSED", 2717 /* 112 */ "EHOSTDOWN", 2718 /* 113 */ "EHOSTUNREACH", 2719 /* 114 */ "EALREADY", 2720 /* 115 */ "EINPROGRESS", 2721 /* 116 */ "ESTALE", 2722 /* 117 */ "EUCLEAN", 2723 /* 118 */ "ENOTNAM", 2724 /* 119 */ "ENAVAIL", 2725 /* 120 */ "EISNAM", 2726 /* 121 */ "EREMOTEIO", 2727 /* 122 */ "EDQUOT", 2728 }; 2729 2730 static char *(linux_signal_names[]) = { 2731 /* 0 */ 0, 2732 /* 1 */ "SIGHUP", 2733 /* 2 */ "SIGINT", 2734 /* 3 */ "SIGQUIT", 2735 /* 4 */ "SIGILL", 2736 /* 5 */ "SIGTRAP", 2737 /* 6 */ "SIGABRT", 2738 /* 6 */ "SIGIOT", 2739 /* 7 */ "SIGBUS", 2740 /* 8 */ "SIGFPE", 2741 /* 9 */ "SIGKILL", 2742 /* 10 */ "SIGUSR1", 2743 /* 11 */ "SIGSEGV", 2744 /* 12 */ "SIGUSR2", 2745 /* 13 */ "SIGPIPE", 2746 /* 14 */ "SIGALRM", 2747 /* 15 */ "SIGTERM", 2748 /* 16 */ "SIGSTKFLT", 2749 /* 17 */ "SIGCHLD", 2750 /* 18 */ "SIGCONT", 2751 /* 19 */ "SIGSTOP", 2752 /* 20 */ "SIGTSTP", 2753 /* 21 */ "SIGTTIN", 2754 /* 22 */ "SIGTTOU", 2755 /* 23 */ "SIGURG", 2756 /* 24 */ "SIGXCPU", 2757 /* 25 */ "SIGXFSZ", 2758 /* 26 */ "SIGVTALRM", 2759 /* 27 */ "SIGPROF", 2760 /* 28 */ "SIGWINCH", 2761 /* 29 */ "SIGIO", 2762 /* 30 */ "SIGPWR", 2763 /* 31 */ "SIGUNUSED", 2764 }; 2765 2766 static emul_syscall emul_linux_syscalls = { 2767 linux_descriptors, 2768 sizeof(linux_descriptors) / sizeof(linux_descriptors[0]), 2769 linux_error_names, 2770 sizeof(linux_error_names) / sizeof(linux_error_names[0]), 2771 linux_signal_names, 2772 sizeof(linux_signal_names) / sizeof(linux_signal_names[0]), 2773 }; 2774 2775 2776 /* Linux's os_emul interface, most are just passed on to the generic 2777 syscall stuff */ 2778 2779 static os_emul_data * 2780 emul_linux_create(device *root, 2781 bfd *image, 2782 const char *name) 2783 { 2784 /* check that this emulation is really for us */ 2785 if (name != NULL && strcmp(name, "linux") != 0) 2786 return NULL; 2787 2788 if (image == NULL) 2789 return NULL; 2790 2791 return emul_unix_create(root, image, "linux", &emul_linux_syscalls); 2792 } 2793 2794 static void 2795 emul_linux_init(os_emul_data *emul_data, 2796 int nr_cpus) 2797 { 2798 /* nothing yet */ 2799 } 2800 2801 static void 2802 emul_linux_system_call(cpu *processor, 2803 unsigned_word cia, 2804 os_emul_data *emul_data) 2805 { 2806 emul_do_system_call(emul_data, 2807 emul_data->syscalls, 2808 cpu_registers(processor)->gpr[0], 2809 3, /*r3 contains arg0*/ 2810 processor, 2811 cia); 2812 } 2813 2814 const os_emul emul_linux = { 2815 "linux", 2816 emul_linux_create, 2817 emul_linux_init, 2818 emul_linux_system_call, 2819 0, /*instruction_call*/ 2820 0 /*data*/ 2821 }; 2822 2823 #endif /* _EMUL_UNIX_C_ */ 2824