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