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