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