1/* CRIS exception, interrupt, and trap (EIT) support 2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011 3 Free Software Foundation, Inc. 4 Contributed by Axis Communications. 5 6This file is part of the GNU simulators. 7 8This program is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 3 of the License, or 11(at your option) any later version. 12 13This program is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21#include "sim-main.h" 22#include "sim-options.h" 23#include "bfd.h" 24/* FIXME: get rid of targ-vals.h usage everywhere else. */ 25 26#include <stdarg.h> 27#ifdef HAVE_ERRNO_H 28#include <errno.h> 29#endif 30#ifdef HAVE_UNISTD_H 31#include <unistd.h> 32#endif 33#ifdef HAVE_FCNTL_H 34#include <fcntl.h> 35#endif 36#ifdef HAVE_SYS_PARAM_H 37#include <sys/param.h> 38#endif 39#ifdef HAVE_SYS_STAT_H 40#include <sys/stat.h> 41#endif 42/* For PATH_MAX, originally. */ 43#ifdef HAVE_LIMITS_H 44#include <limits.h> 45#endif 46 47/* From ld/sysdep.h. */ 48#ifdef PATH_MAX 49# define SIM_PATHMAX PATH_MAX 50#else 51# ifdef MAXPATHLEN 52# define SIM_PATHMAX MAXPATHLEN 53# else 54# define SIM_PATHMAX 1024 55# endif 56#endif 57 58/* The verbatim values are from asm-cris/unistd.h. */ 59 60#define TARGET_SYS_exit 1 61#define TARGET_SYS_read 3 62#define TARGET_SYS_write 4 63#define TARGET_SYS_open 5 64#define TARGET_SYS_close 6 65#define TARGET_SYS_unlink 10 66#define TARGET_SYS_time 13 67#define TARGET_SYS_lseek 19 68#define TARGET_SYS_getpid 20 69#define TARGET_SYS_access 33 70#define TARGET_SYS_kill 37 71#define TARGET_SYS_rename 38 72#define TARGET_SYS_pipe 42 73#define TARGET_SYS_brk 45 74#define TARGET_SYS_ioctl 54 75#define TARGET_SYS_fcntl 55 76#define TARGET_SYS_getppid 64 77#define TARGET_SYS_setrlimit 75 78#define TARGET_SYS_gettimeofday 78 79#define TARGET_SYS_readlink 85 80#define TARGET_SYS_munmap 91 81#define TARGET_SYS_truncate 92 82#define TARGET_SYS_ftruncate 93 83#define TARGET_SYS_socketcall 102 84#define TARGET_SYS_stat 106 85#define TARGET_SYS_fstat 108 86#define TARGET_SYS_wait4 114 87#define TARGET_SYS_sigreturn 119 88#define TARGET_SYS_clone 120 89#define TARGET_SYS_uname 122 90#define TARGET_SYS_mprotect 125 91#define TARGET_SYS_llseek 140 92#define TARGET_SYS_writev 146 93#define TARGET_SYS__sysctl 149 94#define TARGET_SYS_sched_setparam 154 95#define TARGET_SYS_sched_getparam 155 96#define TARGET_SYS_sched_setscheduler 156 97#define TARGET_SYS_sched_getscheduler 157 98#define TARGET_SYS_sched_yield 158 99#define TARGET_SYS_sched_get_priority_max 159 100#define TARGET_SYS_sched_get_priority_min 160 101#define TARGET_SYS_mremap 163 102#define TARGET_SYS_poll 168 103#define TARGET_SYS_rt_sigaction 174 104#define TARGET_SYS_rt_sigprocmask 175 105#define TARGET_SYS_rt_sigsuspend 179 106#define TARGET_SYS_getcwd 183 107#define TARGET_SYS_ugetrlimit 191 108#define TARGET_SYS_mmap2 192 109#define TARGET_SYS_stat64 195 110#define TARGET_SYS_lstat64 196 111#define TARGET_SYS_fstat64 197 112#define TARGET_SYS_geteuid32 201 113#define TARGET_SYS_getuid32 199 114#define TARGET_SYS_getegid32 202 115#define TARGET_SYS_getgid32 200 116#define TARGET_SYS_fcntl64 221 117#define TARGET_SYS_set_thread_area 243 118#define TARGET_SYS_exit_group 252 119 120#define TARGET_PROT_READ 0x1 121#define TARGET_PROT_WRITE 0x2 122#define TARGET_PROT_EXEC 0x4 123#define TARGET_PROT_NONE 0x0 124 125#define TARGET_MAP_SHARED 0x01 126#define TARGET_MAP_PRIVATE 0x02 127#define TARGET_MAP_TYPE 0x0f 128#define TARGET_MAP_FIXED 0x10 129#define TARGET_MAP_ANONYMOUS 0x20 130#define TARGET_MAP_DENYWRITE 0x800 131 132#define TARGET_CTL_KERN 1 133#define TARGET_CTL_VM 2 134#define TARGET_CTL_NET 3 135#define TARGET_CTL_PROC 4 136#define TARGET_CTL_FS 5 137#define TARGET_CTL_DEBUG 6 138#define TARGET_CTL_DEV 7 139#define TARGET_CTL_BUS 8 140#define TARGET_CTL_ABI 9 141 142#define TARGET_CTL_KERN_VERSION 4 143 144/* linux/mman.h */ 145#define TARGET_MREMAP_MAYMOVE 1 146#define TARGET_MREMAP_FIXED 2 147 148#define TARGET_TCGETS 0x5401 149 150#define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009" 151 152/* Seconds since 1970-01-01 to the above date + 10 minutes; 153 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */ 154#define TARGET_EPOCH 1230764410 155 156/* Milliseconds since start of run. We use the number of syscalls to 157 avoid introducing noise in the execution time. */ 158#define TARGET_TIME_MS(cpu) ((cpu)->syscalls) 159 160/* Seconds as in time(2). */ 161#define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000) 162 163#define TARGET_SCHED_OTHER 0 164 165#define TARGET_RLIMIT_STACK 3 166#define TARGET_RLIMIT_NOFILE 7 167 168#define SIM_TARGET_MAX_THREADS 64 169#define SIM_MAX_ALLOC_CHUNK (512*1024*1024) 170 171/* From linux/sched.h. */ 172#define TARGET_CSIGNAL 0x000000ff 173#define TARGET_CLONE_VM 0x00000100 174#define TARGET_CLONE_FS 0x00000200 175#define TARGET_CLONE_FILES 0x00000400 176#define TARGET_CLONE_SIGHAND 0x00000800 177#define TARGET_CLONE_PID 0x00001000 178#define TARGET_CLONE_PTRACE 0x00002000 179#define TARGET_CLONE_VFORK 0x00004000 180#define TARGET_CLONE_PARENT 0x00008000 181#define TARGET_CLONE_THREAD 0x00010000 182#define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD) 183 184/* From asm-cris/poll.h. */ 185#define TARGET_POLLIN 1 186 187/* From asm-cris/signal.h. */ 188#define TARGET_SIG_BLOCK 0 189#define TARGET_SIG_UNBLOCK 1 190#define TARGET_SIG_SETMASK 2 191 192#define TARGET_SIG_DFL 0 193#define TARGET_SIG_IGN 1 194#define TARGET_SIG_ERR ((USI)-1) 195 196#define TARGET_SIGHUP 1 197#define TARGET_SIGINT 2 198#define TARGET_SIGQUIT 3 199#define TARGET_SIGILL 4 200#define TARGET_SIGTRAP 5 201#define TARGET_SIGABRT 6 202#define TARGET_SIGIOT 6 203#define TARGET_SIGBUS 7 204#define TARGET_SIGFPE 8 205#define TARGET_SIGKILL 9 206#define TARGET_SIGUSR1 10 207#define TARGET_SIGSEGV 11 208#define TARGET_SIGUSR2 12 209#define TARGET_SIGPIPE 13 210#define TARGET_SIGALRM 14 211#define TARGET_SIGTERM 15 212#define TARGET_SIGSTKFLT 16 213#define TARGET_SIGCHLD 17 214#define TARGET_SIGCONT 18 215#define TARGET_SIGSTOP 19 216#define TARGET_SIGTSTP 20 217#define TARGET_SIGTTIN 21 218#define TARGET_SIGTTOU 22 219#define TARGET_SIGURG 23 220#define TARGET_SIGXCPU 24 221#define TARGET_SIGXFSZ 25 222#define TARGET_SIGVTALRM 26 223#define TARGET_SIGPROF 27 224#define TARGET_SIGWINCH 28 225#define TARGET_SIGIO 29 226#define TARGET_SIGPOLL SIGIO 227/* Actually commented out in the kernel header. */ 228#define TARGET_SIGLOST 29 229#define TARGET_SIGPWR 30 230#define TARGET_SIGSYS 31 231 232/* From include/asm-cris/signal.h. */ 233#define TARGET_SA_NOCLDSTOP 0x00000001 234#define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */ 235#define TARGET_SA_SIGINFO 0x00000004 236#define TARGET_SA_ONSTACK 0x08000000 237#define TARGET_SA_RESTART 0x10000000 238#define TARGET_SA_NODEFER 0x40000000 239#define TARGET_SA_RESETHAND 0x80000000 240#define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */ 241#define TARGET_SA_RESTORER 0x04000000 242 243/* From linux/wait.h. */ 244#define TARGET_WNOHANG 1 245#define TARGET_WUNTRACED 2 246#define TARGET___WNOTHREAD 0x20000000 247#define TARGET___WALL 0x40000000 248#define TARGET___WCLONE 0x80000000 249 250/* From linux/limits.h. */ 251#define TARGET_PIPE_BUF 4096 252 253/* From unistd.h. */ 254#define TARGET_R_OK 4 255#define TARGET_W_OK 2 256#define TARGET_X_OK 1 257#define TARGET_F_OK 0 258 259static const char stat_map[] = 260"st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4" 261":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4" 262":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4" 263":st_ino,8"; 264 265static const CB_TARGET_DEFS_MAP syscall_map[] = 266{ 267 { CB_SYS_open, TARGET_SYS_open }, 268 { CB_SYS_close, TARGET_SYS_close }, 269 { CB_SYS_read, TARGET_SYS_read }, 270 { CB_SYS_write, TARGET_SYS_write }, 271 { CB_SYS_lseek, TARGET_SYS_lseek }, 272 { CB_SYS_unlink, TARGET_SYS_unlink }, 273 { CB_SYS_getpid, TARGET_SYS_getpid }, 274 { CB_SYS_fstat, TARGET_SYS_fstat64 }, 275 { CB_SYS_lstat, TARGET_SYS_lstat64 }, 276 { CB_SYS_stat, TARGET_SYS_stat64 }, 277 { CB_SYS_pipe, TARGET_SYS_pipe }, 278 { CB_SYS_rename, TARGET_SYS_rename }, 279 { CB_SYS_truncate, TARGET_SYS_truncate }, 280 { CB_SYS_ftruncate, TARGET_SYS_ftruncate }, 281 { 0, -1 } 282}; 283 284/* An older, 32-bit-only stat mapping. */ 285static const char stat32_map[] = 286"st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2" 287":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4" 288":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12"; 289 290/* Map for calls using the 32-bit struct stat. Primarily used by the 291 newlib Linux mapping. */ 292static const CB_TARGET_DEFS_MAP syscall_stat32_map[] = 293{ 294 { CB_SYS_fstat, TARGET_SYS_fstat }, 295 { CB_SYS_stat, TARGET_SYS_stat }, 296 { 0, -1 } 297}; 298 299/* Giving the true value for the running sim process will lead to 300 non-time-invariant behavior. */ 301#define TARGET_PID 42 302 303/* Unfortunately, we don't get this from cris.cpu at the moment, and if 304 we did, we'd still don't get a register number with the "16" offset. */ 305#define TARGET_SRP_REGNUM (16+11) 306 307/* Extracted by applying 308 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}' 309 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and 310 adjusting the synonyms. */ 311 312static const CB_TARGET_DEFS_MAP errno_map[] = 313{ 314#ifdef EPERM 315 { EPERM, 1 }, 316#endif 317#ifdef ENOENT 318 { ENOENT, 2 }, 319#endif 320#ifdef ESRCH 321 { ESRCH, 3 }, 322#endif 323#ifdef EINTR 324 { EINTR, 4 }, 325#endif 326#ifdef EIO 327 { EIO, 5 }, 328#endif 329#ifdef ENXIO 330 { ENXIO, 6 }, 331#endif 332#ifdef E2BIG 333 { E2BIG, 7 }, 334#endif 335#ifdef ENOEXEC 336 { ENOEXEC, 8 }, 337#endif 338#ifdef EBADF 339 { EBADF, 9 }, 340#endif 341#ifdef ECHILD 342 { ECHILD, 10 }, 343#endif 344#ifdef EAGAIN 345 { EAGAIN, 11 }, 346#endif 347#ifdef ENOMEM 348 { ENOMEM, 12 }, 349#endif 350#ifdef EACCES 351 { EACCES, 13 }, 352#endif 353#ifdef EFAULT 354 { EFAULT, 14 }, 355#endif 356#ifdef ENOTBLK 357 { ENOTBLK, 15 }, 358#endif 359#ifdef EBUSY 360 { EBUSY, 16 }, 361#endif 362#ifdef EEXIST 363 { EEXIST, 17 }, 364#endif 365#ifdef EXDEV 366 { EXDEV, 18 }, 367#endif 368#ifdef ENODEV 369 { ENODEV, 19 }, 370#endif 371#ifdef ENOTDIR 372 { ENOTDIR, 20 }, 373#endif 374#ifdef EISDIR 375 { EISDIR, 21 }, 376#endif 377#ifdef EINVAL 378 { EINVAL, 22 }, 379#endif 380#ifdef ENFILE 381 { ENFILE, 23 }, 382#endif 383#ifdef EMFILE 384 { EMFILE, 24 }, 385#endif 386#ifdef ENOTTY 387 { ENOTTY, 25 }, 388#endif 389#ifdef ETXTBSY 390 { ETXTBSY, 26 }, 391#endif 392#ifdef EFBIG 393 { EFBIG, 27 }, 394#endif 395#ifdef ENOSPC 396 { ENOSPC, 28 }, 397#endif 398#ifdef ESPIPE 399 { ESPIPE, 29 }, 400#endif 401#ifdef EROFS 402 { EROFS, 30 }, 403#endif 404#ifdef EMLINK 405 { EMLINK, 31 }, 406#endif 407#ifdef EPIPE 408 { EPIPE, 32 }, 409#endif 410#ifdef EDOM 411 { EDOM, 33 }, 412#endif 413#ifdef ERANGE 414 { ERANGE, 34 }, 415#endif 416#ifdef EDEADLK 417 { EDEADLK, 35 }, 418#endif 419#ifdef ENAMETOOLONG 420 { ENAMETOOLONG, 36 }, 421#endif 422#ifdef ENOLCK 423 { ENOLCK, 37 }, 424#endif 425#ifdef ENOSYS 426 { ENOSYS, 38 }, 427#endif 428#ifdef ENOTEMPTY 429 { ENOTEMPTY, 39 }, 430#endif 431#ifdef ELOOP 432 { ELOOP, 40 }, 433#endif 434#ifdef EWOULDBLOCK 435 { EWOULDBLOCK, 11 }, 436#endif 437#ifdef ENOMSG 438 { ENOMSG, 42 }, 439#endif 440#ifdef EIDRM 441 { EIDRM, 43 }, 442#endif 443#ifdef ECHRNG 444 { ECHRNG, 44 }, 445#endif 446#ifdef EL2NSYNC 447 { EL2NSYNC, 45 }, 448#endif 449#ifdef EL3HLT 450 { EL3HLT, 46 }, 451#endif 452#ifdef EL3RST 453 { EL3RST, 47 }, 454#endif 455#ifdef ELNRNG 456 { ELNRNG, 48 }, 457#endif 458#ifdef EUNATCH 459 { EUNATCH, 49 }, 460#endif 461#ifdef ENOCSI 462 { ENOCSI, 50 }, 463#endif 464#ifdef EL2HLT 465 { EL2HLT, 51 }, 466#endif 467#ifdef EBADE 468 { EBADE, 52 }, 469#endif 470#ifdef EBADR 471 { EBADR, 53 }, 472#endif 473#ifdef EXFULL 474 { EXFULL, 54 }, 475#endif 476#ifdef ENOANO 477 { ENOANO, 55 }, 478#endif 479#ifdef EBADRQC 480 { EBADRQC, 56 }, 481#endif 482#ifdef EBADSLT 483 { EBADSLT, 57 }, 484#endif 485#ifdef EDEADLOCK 486 { EDEADLOCK, 35 }, 487#endif 488#ifdef EBFONT 489 { EBFONT, 59 }, 490#endif 491#ifdef ENOSTR 492 { ENOSTR, 60 }, 493#endif 494#ifdef ENODATA 495 { ENODATA, 61 }, 496#endif 497#ifdef ETIME 498 { ETIME, 62 }, 499#endif 500#ifdef ENOSR 501 { ENOSR, 63 }, 502#endif 503#ifdef ENONET 504 { ENONET, 64 }, 505#endif 506#ifdef ENOPKG 507 { ENOPKG, 65 }, 508#endif 509#ifdef EREMOTE 510 { EREMOTE, 66 }, 511#endif 512#ifdef ENOLINK 513 { ENOLINK, 67 }, 514#endif 515#ifdef EADV 516 { EADV, 68 }, 517#endif 518#ifdef ESRMNT 519 { ESRMNT, 69 }, 520#endif 521#ifdef ECOMM 522 { ECOMM, 70 }, 523#endif 524#ifdef EPROTO 525 { EPROTO, 71 }, 526#endif 527#ifdef EMULTIHOP 528 { EMULTIHOP, 72 }, 529#endif 530#ifdef EDOTDOT 531 { EDOTDOT, 73 }, 532#endif 533#ifdef EBADMSG 534 { EBADMSG, 74 }, 535#endif 536#ifdef EOVERFLOW 537 { EOVERFLOW, 75 }, 538#endif 539#ifdef ENOTUNIQ 540 { ENOTUNIQ, 76 }, 541#endif 542#ifdef EBADFD 543 { EBADFD, 77 }, 544#endif 545#ifdef EREMCHG 546 { EREMCHG, 78 }, 547#endif 548#ifdef ELIBACC 549 { ELIBACC, 79 }, 550#endif 551#ifdef ELIBBAD 552 { ELIBBAD, 80 }, 553#endif 554#ifdef ELIBSCN 555 { ELIBSCN, 81 }, 556#endif 557#ifdef ELIBMAX 558 { ELIBMAX, 82 }, 559#endif 560#ifdef ELIBEXEC 561 { ELIBEXEC, 83 }, 562#endif 563#ifdef EILSEQ 564 { EILSEQ, 84 }, 565#endif 566#ifdef ERESTART 567 { ERESTART, 85 }, 568#endif 569#ifdef ESTRPIPE 570 { ESTRPIPE, 86 }, 571#endif 572#ifdef EUSERS 573 { EUSERS, 87 }, 574#endif 575#ifdef ENOTSOCK 576 { ENOTSOCK, 88 }, 577#endif 578#ifdef EDESTADDRREQ 579 { EDESTADDRREQ, 89 }, 580#endif 581#ifdef EMSGSIZE 582 { EMSGSIZE, 90 }, 583#endif 584#ifdef EPROTOTYPE 585 { EPROTOTYPE, 91 }, 586#endif 587#ifdef ENOPROTOOPT 588 { ENOPROTOOPT, 92 }, 589#endif 590#ifdef EPROTONOSUPPORT 591 { EPROTONOSUPPORT, 93 }, 592#endif 593#ifdef ESOCKTNOSUPPORT 594 { ESOCKTNOSUPPORT, 94 }, 595#endif 596#ifdef EOPNOTSUPP 597 { EOPNOTSUPP, 95 }, 598#endif 599#ifdef EPFNOSUPPORT 600 { EPFNOSUPPORT, 96 }, 601#endif 602#ifdef EAFNOSUPPORT 603 { EAFNOSUPPORT, 97 }, 604#endif 605#ifdef EADDRINUSE 606 { EADDRINUSE, 98 }, 607#endif 608#ifdef EADDRNOTAVAIL 609 { EADDRNOTAVAIL, 99 }, 610#endif 611#ifdef ENETDOWN 612 { ENETDOWN, 100 }, 613#endif 614#ifdef ENETUNREACH 615 { ENETUNREACH, 101 }, 616#endif 617#ifdef ENETRESET 618 { ENETRESET, 102 }, 619#endif 620#ifdef ECONNABORTED 621 { ECONNABORTED, 103 }, 622#endif 623#ifdef ECONNRESET 624 { ECONNRESET, 104 }, 625#endif 626#ifdef ENOBUFS 627 { ENOBUFS, 105 }, 628#endif 629#ifdef EISCONN 630 { EISCONN, 106 }, 631#endif 632#ifdef ENOTCONN 633 { ENOTCONN, 107 }, 634#endif 635#ifdef ESHUTDOWN 636 { ESHUTDOWN, 108 }, 637#endif 638#ifdef ETOOMANYREFS 639 { ETOOMANYREFS, 109 }, 640#endif 641#ifdef ETIMEDOUT 642 { ETIMEDOUT, 110 }, 643#endif 644#ifdef ECONNREFUSED 645 { ECONNREFUSED, 111 }, 646#endif 647#ifdef EHOSTDOWN 648 { EHOSTDOWN, 112 }, 649#endif 650#ifdef EHOSTUNREACH 651 { EHOSTUNREACH, 113 }, 652#endif 653#ifdef EALREADY 654 { EALREADY, 114 }, 655#endif 656#ifdef EINPROGRESS 657 { EINPROGRESS, 115 }, 658#endif 659#ifdef ESTALE 660 { ESTALE, 116 }, 661#endif 662#ifdef EUCLEAN 663 { EUCLEAN, 117 }, 664#endif 665#ifdef ENOTNAM 666 { ENOTNAM, 118 }, 667#endif 668#ifdef ENAVAIL 669 { ENAVAIL, 119 }, 670#endif 671#ifdef EISNAM 672 { EISNAM, 120 }, 673#endif 674#ifdef EREMOTEIO 675 { EREMOTEIO, 121 }, 676#endif 677#ifdef EDQUOT 678 { EDQUOT, 122 }, 679#endif 680#ifdef ENOMEDIUM 681 { ENOMEDIUM, 123 }, 682#endif 683#ifdef EMEDIUMTYPE 684 { EMEDIUMTYPE, 124 }, 685#endif 686 { 0, -1 } 687}; 688 689/* Extracted by applying 690 perl -ne 'if ($_ =~ /^#define/) { split; 691 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n", 692 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}' 693 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS 694 installation and removing synonyms and unnecessary items. Don't 695 forget the end-marker. */ 696 697/* These we treat specially, as they're used in the fcntl F_GETFL 698 syscall. For consistency, open_map is also manually edited to use 699 these macros. */ 700#define TARGET_O_ACCMODE 0x3 701#define TARGET_O_RDONLY 0x0 702#define TARGET_O_WRONLY 0x1 703 704static const CB_TARGET_DEFS_MAP open_map[] = { 705#ifdef O_ACCMODE 706 { O_ACCMODE, TARGET_O_ACCMODE }, 707#endif 708#ifdef O_RDONLY 709 { O_RDONLY, TARGET_O_RDONLY }, 710#endif 711#ifdef O_WRONLY 712 { O_WRONLY, TARGET_O_WRONLY }, 713#endif 714#ifdef O_RDWR 715 { O_RDWR, 0x2 }, 716#endif 717#ifdef O_CREAT 718 { O_CREAT, 0x40 }, 719#endif 720#ifdef O_EXCL 721 { O_EXCL, 0x80 }, 722#endif 723#ifdef O_NOCTTY 724 { O_NOCTTY, 0x100 }, 725#endif 726#ifdef O_TRUNC 727 { O_TRUNC, 0x200 }, 728#endif 729#ifdef O_APPEND 730 { O_APPEND, 0x400 }, 731#endif 732#ifdef O_NONBLOCK 733 { O_NONBLOCK, 0x800 }, 734#endif 735#ifdef O_NDELAY 736 { O_NDELAY, 0x0 }, 737#endif 738#ifdef O_SYNC 739 { O_SYNC, 0x1000 }, 740#endif 741#ifdef FASYNC 742 { FASYNC, 0x2000 }, 743#endif 744#ifdef O_DIRECT 745 { O_DIRECT, 0x4000 }, 746#endif 747#ifdef O_LARGEFILE 748 { O_LARGEFILE, 0x8000 }, 749#endif 750#ifdef O_DIRECTORY 751 { O_DIRECTORY, 0x10000 }, 752#endif 753#ifdef O_NOFOLLOW 754 { O_NOFOLLOW, 0x20000 }, 755#endif 756 { -1, -1 } 757}; 758 759/* Let's be less drastic and more traceable. FIXME: mark as noreturn. */ 760#define abort() \ 761 sim_io_error (sd, "simulator unhandled condition at %s:%d", \ 762 __FUNCTION__, __LINE__) 763 764/* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */ 765static SIM_CPU *current_cpu_for_cb_callback; 766 767static int syscall_read_mem (host_callback *, struct cb_syscall *, 768 unsigned long, char *, int); 769static int syscall_write_mem (host_callback *, struct cb_syscall *, 770 unsigned long, const char *, int); 771static USI create_map (SIM_DESC, struct cris_sim_mmapped_page **, 772 USI addr, USI len); 773static USI unmap_pages (SIM_DESC, struct cris_sim_mmapped_page **, 774 USI addr, USI len); 775static USI is_mapped (SIM_DESC, struct cris_sim_mmapped_page **, 776 USI addr, USI len); 777static void dump_statistics (SIM_CPU *current_cpu); 778static void make_first_thread (SIM_CPU *current_cpu); 779 780/* Read/write functions for system call interface. */ 781 782static int 783syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED, 784 struct cb_syscall *sc, 785 unsigned long taddr, char *buf, int bytes) 786{ 787 SIM_DESC sd = (SIM_DESC) sc->p1; 788 SIM_CPU *cpu = (SIM_CPU *) sc->p2; 789 790 return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes); 791} 792 793static int 794syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED, 795 struct cb_syscall *sc, 796 unsigned long taddr, const char *buf, int bytes) 797{ 798 SIM_DESC sd = (SIM_DESC) sc->p1; 799 SIM_CPU *cpu = (SIM_CPU *) sc->p2; 800 801 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); 802} 803 804/* When we risk running self-modified code (as in trampolines), this is 805 called from special-case insns. The silicon CRIS CPU:s have enough 806 cache snooping implemented making this a simulator-only issue. Tests: 807 gcc.c-torture/execute/931002-1.c execution, -O3 -g 808 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */ 809 810void 811cris_flush_simulator_decode_cache (SIM_CPU *current_cpu, 812 USI pc ATTRIBUTE_UNUSED) 813{ 814 SIM_DESC sd = CPU_STATE (current_cpu); 815 816#if WITH_SCACHE 817 if (USING_SCACHE_P (sd)) 818 scache_flush_cpu (current_cpu); 819#endif 820} 821 822/* Output statistics at the end of a run. */ 823static void 824dump_statistics (SIM_CPU *current_cpu) 825{ 826 SIM_DESC sd = CPU_STATE (current_cpu); 827 CRIS_MISC_PROFILE *profp 828 = CPU_CRIS_MISC_PROFILE (current_cpu); 829 unsigned64 total = profp->basic_cycle_count; 830 const char *textmsg = "Basic clock cycles, total @: %llu\n"; 831 832 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect 833 what's included in the "total" count only. */ 834 switch (CPU_CRIS_MISC_PROFILE (current_cpu)->flags 835 & FLAG_CRIS_MISC_PROFILE_ALL) 836 { 837 case FLAG_CRIS_MISC_PROFILE_SIMPLE: 838 break; 839 840 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED | FLAG_CRIS_MISC_PROFILE_SIMPLE): 841 textmsg 842 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n"; 843 total += profp->unaligned_mem_dword_count; 844 break; 845 846 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE | FLAG_CRIS_MISC_PROFILE_SIMPLE): 847 textmsg = "Schedulable clock cycles, total @: %llu\n"; 848 total 849 += (profp->memsrc_stall_count 850 + profp->memraw_stall_count 851 + profp->movemsrc_stall_count 852 + profp->movemdst_stall_count 853 + profp->mulsrc_stall_count 854 + profp->jumpsrc_stall_count 855 + profp->unaligned_mem_dword_count); 856 break; 857 858 case FLAG_CRIS_MISC_PROFILE_ALL: 859 textmsg = "All accounted clock cycles, total @: %llu\n"; 860 total 861 += (profp->memsrc_stall_count 862 + profp->memraw_stall_count 863 + profp->movemsrc_stall_count 864 + profp->movemdst_stall_count 865 + profp->movemaddr_stall_count 866 + profp->mulsrc_stall_count 867 + profp->jumpsrc_stall_count 868 + profp->branch_stall_count 869 + profp->jumptarget_stall_count 870 + profp->unaligned_mem_dword_count); 871 break; 872 873 default: 874 abort (); 875 876 sim_io_eprintf (sd, 877 "Internal inconsistency at %s:%d", 878 __FILE__, __LINE__); 879 sim_engine_halt (sd, current_cpu, NULL, 0, 880 sim_stopped, SIM_SIGILL); 881 } 882 883 /* Historically, these messages have gone to stderr, so we'll keep it 884 that way. It's also easier to then tell it from normal program 885 output. FIXME: Add redirect option like "run -e file". */ 886 sim_io_eprintf (sd, textmsg, total); 887 888 /* For v32, unaligned_mem_dword_count should always be 0. For 889 v10, memsrc_stall_count should always be 0. */ 890 sim_io_eprintf (sd, "Memory source stall cycles: %llu\n", 891 (unsigned long long) (profp->memsrc_stall_count 892 + profp->unaligned_mem_dword_count)); 893 sim_io_eprintf (sd, "Memory read-after-write stall cycles: %llu\n", 894 (unsigned long long) profp->memraw_stall_count); 895 sim_io_eprintf (sd, "Movem source stall cycles: %llu\n", 896 (unsigned long long) profp->movemsrc_stall_count); 897 sim_io_eprintf (sd, "Movem destination stall cycles: %llu\n", 898 (unsigned long long) profp->movemdst_stall_count); 899 sim_io_eprintf (sd, "Movem address stall cycles: %llu\n", 900 (unsigned long long) profp->movemaddr_stall_count); 901 sim_io_eprintf (sd, "Multiplication source stall cycles: %llu\n", 902 (unsigned long long) profp->mulsrc_stall_count); 903 sim_io_eprintf (sd, "Jump source stall cycles: %llu\n", 904 (unsigned long long) profp->jumpsrc_stall_count); 905 sim_io_eprintf (sd, "Branch misprediction stall cycles: %llu\n", 906 (unsigned long long) profp->branch_stall_count); 907 sim_io_eprintf (sd, "Jump target stall cycles: %llu\n", 908 (unsigned long long) profp->jumptarget_stall_count); 909} 910 911/* Check whether any part of [addr .. addr + len - 1] is already mapped. 912 Return 1 if a overlap detected, 0 otherwise. */ 913 914static USI 915is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED, 916 struct cris_sim_mmapped_page **rootp, 917 USI addr, USI len) 918{ 919 struct cris_sim_mmapped_page *mapp; 920 921 if (len == 0 || (len & 8191)) 922 abort (); 923 924 /* Iterate over the reverse-address sorted pages until we find a page in 925 or lower than the checked area. */ 926 for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev) 927 if (mapp->addr < addr + len && mapp->addr >= addr) 928 return 1; 929 930 return 0; 931} 932 933/* Check whether any part of [addr .. addr + len - 1] is *un*mapped. 934 Return 1 if the whole area is mapped, 0 otherwise. */ 935 936static USI 937is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED, 938 struct cris_sim_mmapped_page **rootp, 939 USI addr, USI len) 940{ 941 struct cris_sim_mmapped_page *mapp; 942 943 if (len == 0 || (len & 8191)) 944 abort (); 945 946 /* Iterate over the reverse-address sorted pages until we find a page 947 lower than the checked area. */ 948 for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev) 949 if (addr == mapp->addr && len == 8192) 950 return 1; 951 else if (addr + len > mapp->addr) 952 len -= 8192; 953 954 return 0; 955} 956 957/* Debug helper; to be run from gdb. */ 958 959void 960cris_dump_map (SIM_CPU *current_cpu) 961{ 962 struct cris_sim_mmapped_page *mapp; 963 USI start, end; 964 965 for (mapp = current_cpu->highest_mmapped_page, 966 start = mapp == NULL ? 0 : mapp->addr + 8192, 967 end = mapp == NULL ? 0 : mapp->addr + 8191; 968 mapp != NULL; 969 mapp = mapp->prev) 970 { 971 if (mapp->addr != start - 8192) 972 { 973 sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end); 974 end = mapp->addr + 8191; 975 } 976 977 start = mapp->addr; 978 } 979 980 if (current_cpu->highest_mmapped_page != NULL) 981 sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end); 982} 983 984/* Create mmapped memory. ADDR is -1 if any address will do. Caller 985 must make sure that the address isn't already mapped. */ 986 987static USI 988create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr, 989 USI len) 990{ 991 struct cris_sim_mmapped_page *mapp; 992 struct cris_sim_mmapped_page **higher_prevp = rootp; 993 USI new_addr = 0x40000000; 994 995 if (addr != (USI) -1) 996 new_addr = addr; 997 else if (*rootp && rootp[0]->addr >= new_addr) 998 new_addr = rootp[0]->addr + 8192; 999 1000 if (len != 8192) 1001 { 1002 USI page_addr; 1003 1004 if (len & 8191) 1005 /* Which is better: return an error for this, or just round it up? */ 1006 abort (); 1007 1008 /* Do a recursive call for each page in the request. */ 1009 for (page_addr = new_addr; len != 0; page_addr += 8192, len -= 8192) 1010 if (create_map (sd, rootp, page_addr, 8192) >= (USI) -8191) 1011 abort (); 1012 1013 return new_addr; 1014 } 1015 1016 for (mapp = *rootp; 1017 mapp != NULL && mapp->addr > new_addr; 1018 mapp = mapp->prev) 1019 higher_prevp = &mapp->prev; 1020 1021 /* Assert for consistency that we don't create duplicate maps. */ 1022 if (is_mapped (sd, rootp, new_addr, len)) 1023 abort (); 1024 1025 /* Allocate the new page, on the next higher page from the last one 1026 allocated, and link in the new descriptor before previous ones. */ 1027 mapp = malloc (sizeof (*mapp)); 1028 1029 if (mapp == NULL) 1030 return (USI) -ENOMEM; 1031 1032 sim_core_attach (sd, NULL, 0, access_read_write_exec, 0, 1033 new_addr, len, 1034 0, NULL, NULL); 1035 1036 mapp->addr = new_addr; 1037 mapp->prev = *higher_prevp; 1038 *higher_prevp = mapp; 1039 1040 return new_addr; 1041} 1042 1043/* Unmap one or more pages. */ 1044 1045static USI 1046unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr, 1047 USI len) 1048{ 1049 struct cris_sim_mmapped_page *mapp; 1050 struct cris_sim_mmapped_page **higher_prevp = rootp; 1051 1052 if (len != 8192) 1053 { 1054 USI page_addr; 1055 int ret = 0; 1056 1057 if (len & 8191) 1058 /* Which is better: return an error for this, or just round it up? */ 1059 abort (); 1060 1061 /* Loop backwards to make each call is O(1) over the number of pages 1062 allocated, if we're unmapping from the high end of the pages. */ 1063 for (page_addr = addr + len - 8192; 1064 page_addr > addr; 1065 page_addr -= 8192) 1066 if (unmap_pages (sd, rootp, page_addr, 8192)) 1067 ret = EINVAL; 1068 1069 if (unmap_pages (sd, rootp, addr, 8192)) 1070 ret = EINVAL; 1071 1072 return ret; 1073 } 1074 1075 for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev) 1076 higher_prevp = &mapp->prev; 1077 1078 if (mapp == NULL || mapp->addr != addr) 1079 return EINVAL; 1080 1081 *higher_prevp = mapp->prev; 1082 sim_core_detach (sd, NULL, 0, 0, addr); 1083 free (mapp); 1084 return 0; 1085} 1086 1087/* The semantic code invokes this for illegal (unrecognized) instructions. */ 1088 1089SEM_PC 1090sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc) 1091{ 1092 SIM_DESC sd = CPU_STATE (current_cpu); 1093 1094 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL); 1095 return vpc; 1096} 1097 1098/* Handlers from the CGEN description that should not be called. */ 1099 1100USI 1101cris_bmod_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED, 1102 UINT srcreg ATTRIBUTE_UNUSED, 1103 USI dstreg ATTRIBUTE_UNUSED) 1104{ 1105 SIM_DESC sd = CPU_STATE (current_cpu); 1106 abort (); 1107} 1108 1109void 1110h_supr_set_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED, 1111 UINT index ATTRIBUTE_UNUSED, 1112 USI page ATTRIBUTE_UNUSED, 1113 USI newval ATTRIBUTE_UNUSED) 1114{ 1115 SIM_DESC sd = CPU_STATE (current_cpu); 1116 abort (); 1117} 1118 1119USI 1120h_supr_get_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED, 1121 UINT index ATTRIBUTE_UNUSED, 1122 USI page ATTRIBUTE_UNUSED) 1123{ 1124 SIM_DESC sd = CPU_STATE (current_cpu); 1125 abort (); 1126} 1127 1128/* Swap one context for another. */ 1129 1130static void 1131schedule (SIM_CPU *current_cpu, int next) 1132{ 1133 /* Need to mark context-switches in the trace output. */ 1134 if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags 1135 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE)) 1136 cris_trace_printf (CPU_STATE (current_cpu), current_cpu, 1137 "\t#:%d\n", next); 1138 1139 /* Copy the current context (if there is one) to its slot. */ 1140 if (current_cpu->thread_data[current_cpu->threadno].cpu_context) 1141 memcpy (current_cpu->thread_data[current_cpu->threadno].cpu_context, 1142 ¤t_cpu->cpu_data_placeholder, 1143 current_cpu->thread_cpu_data_size); 1144 1145 /* Copy the new context from its slot. */ 1146 memcpy (¤t_cpu->cpu_data_placeholder, 1147 current_cpu->thread_data[next].cpu_context, 1148 current_cpu->thread_cpu_data_size); 1149 1150 /* Update needed stuff to indicate the new context. */ 1151 current_cpu->threadno = next; 1152 1153 /* Handle pending signals. */ 1154 if (current_cpu->thread_data[next].sigpending 1155 /* We don't run nested signal handlers. This means that pause(2) 1156 and sigsuspend(2) do not work in sighandlers, but that 1157 shouldn't be too hard a restriction. It also greatly 1158 simplifies the code. */ 1159 && current_cpu->thread_data[next].cpu_context_atsignal == NULL) 1160 { 1161 int sig; 1162 1163 /* See if there's really a pending, non-blocked handler. We don't 1164 queue signals, so just use the first one in ascending order. */ 1165 for (sig = 0; sig < 64; sig++) 1166 if (current_cpu->thread_data[next].sigdata[sig].pending 1167 && !current_cpu->thread_data[next].sigdata[sig].blocked) 1168 { 1169 bfd_byte regbuf[4]; 1170 USI sp; 1171 int i; 1172 USI blocked; 1173 USI pc = sim_pc_get (current_cpu); 1174 1175 /* It's simpler to save the CPU context inside the simulator 1176 than on the stack. */ 1177 current_cpu->thread_data[next].cpu_context_atsignal 1178 = (*current_cpu 1179 ->make_thread_cpu_data) (current_cpu, 1180 current_cpu->thread_data[next] 1181 .cpu_context); 1182 1183 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4); 1184 sp = bfd_getl32 (regbuf); 1185 1186 /* Make sure we have an aligned stack. */ 1187 sp &= ~3; 1188 1189 /* Make room for the signal frame, aligned. FIXME: Check that 1190 the memory exists, map it in if absent. (BTW, should also 1191 implement on-access automatic stack allocation). */ 1192 sp -= 20; 1193 1194 /* This isn't the same signal frame as the kernel uses, because 1195 we don't want to bother getting all registers on and off the 1196 stack. */ 1197 1198 /* First, we store the currently blocked signals. */ 1199 blocked = 0; 1200 for (i = 0; i < 32; i++) 1201 blocked 1202 |= current_cpu->thread_data[next].sigdata[i + 1].blocked << i; 1203 sim_core_write_aligned_4 (current_cpu, pc, 0, sp, blocked); 1204 blocked = 0; 1205 for (i = 0; i < 31; i++) 1206 blocked 1207 |= current_cpu->thread_data[next].sigdata[i + 33].blocked << i; 1208 sim_core_write_aligned_4 (current_cpu, pc, 0, sp + 4, blocked); 1209 1210 /* Then, the actual instructions. This is CPU-specific, but we 1211 use instructions from the common subset for v10 and v32 which 1212 should be safe for the time being but could be parametrized 1213 if need be. */ 1214 /* MOVU.W [PC+],R9. */ 1215 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 8, 0x9c5f); 1216 /* .WORD TARGET_SYS_sigreturn. */ 1217 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 10, 1218 TARGET_SYS_sigreturn); 1219 /* BREAK 13. */ 1220 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 12, 0xe93d); 1221 1222 /* NOP (on v32; it's SETF on v10, but is the correct compatible 1223 instruction. Still, it doesn't matter because v10 has no 1224 delay slot for BREAK so it will not be executed). */ 1225 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 16, 0x05b0); 1226 1227 /* Modify registers to hold the right values for the sighandler 1228 context: updated stackpointer and return address pointing to 1229 the sigreturn stub. */ 1230 bfd_putl32 (sp, regbuf); 1231 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4); 1232 bfd_putl32 (sp + 8, regbuf); 1233 (*CPU_REG_STORE (current_cpu)) (current_cpu, TARGET_SRP_REGNUM, 1234 regbuf, 4); 1235 1236 current_cpu->thread_data[next].sigdata[sig].pending = 0; 1237 1238 /* Block this signal (for the duration of the sighandler). */ 1239 current_cpu->thread_data[next].sigdata[sig].blocked = 1; 1240 1241 sim_pc_set (current_cpu, current_cpu->sighandler[sig]); 1242 bfd_putl32 (sig, regbuf); 1243 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, 1244 regbuf, 4); 1245 1246 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I 1247 needed all this for, specifies a SA_SIGINFO call but treats it 1248 like an ordinary sighandler; only the signal number argument is 1249 inspected. To make future need to implement SA_SIGINFO 1250 correctly possible, we set the siginfo argument register to a 1251 magic (hopefully non-address) number. (NB: then, you should 1252 just need to pass the siginfo argument; it seems you probably 1253 don't need to implement the specific rt_sigreturn.) */ 1254 bfd_putl32 (0xbad5161f, regbuf); 1255 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R11, 1256 regbuf, 4); 1257 1258 /* The third argument is unused and the kernel sets it to 0. */ 1259 bfd_putl32 (0, regbuf); 1260 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R12, 1261 regbuf, 4); 1262 return; 1263 } 1264 1265 /* No, there actually was no pending signal for this thread. Reset 1266 this flag. */ 1267 current_cpu->thread_data[next].sigpending = 0; 1268 } 1269} 1270 1271/* Reschedule the simplest possible way until something else is absolutely 1272 necessary: 1273 - A. Find the next process (round-robin) that doesn't have at_syscall 1274 set, schedule it. 1275 - B. If there is none, just run the next process, round-robin. 1276 - Clear at_syscall for the current process. */ 1277 1278static void 1279reschedule (SIM_CPU *current_cpu) 1280{ 1281 SIM_DESC sd = CPU_STATE (current_cpu); 1282 int i; 1283 1284 /* Iterate over all thread slots, because after a few thread creations 1285 and exits, we don't know where the live ones are. */ 1286 for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS; 1287 i != current_cpu->threadno; 1288 i = (i + 1) % SIM_TARGET_MAX_THREADS) 1289 if (current_cpu->thread_data[i].cpu_context 1290 && current_cpu->thread_data[i].at_syscall == 0) 1291 { 1292 schedule (current_cpu, i); 1293 return; 1294 } 1295 1296 /* Pick any next live thread. */ 1297 for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS; 1298 i != current_cpu->threadno; 1299 i = (i + 1) % SIM_TARGET_MAX_THREADS) 1300 if (current_cpu->thread_data[i].cpu_context) 1301 { 1302 schedule (current_cpu, i); 1303 return; 1304 } 1305 1306 /* More than one live thread, but we couldn't find the next one? */ 1307 abort (); 1308} 1309 1310/* Set up everything to receive (or IGN) an incoming signal to the 1311 current context. */ 1312 1313static int 1314deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid) 1315{ 1316 int i; 1317 USI pc = sim_pc_get (current_cpu); 1318 1319 /* Find the thread index of the pid. */ 1320 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++) 1321 /* Apparently it's ok to send signals to zombies (so a check for 1322 current_cpu->thread_data[i].cpu_context != NULL would be 1323 wrong). */ 1324 if (current_cpu->thread_data[i].threadid == pid - TARGET_PID) 1325 { 1326 if (sig < 64) 1327 switch (current_cpu->sighandler[sig]) 1328 { 1329 case TARGET_SIG_DFL: 1330 switch (sig) 1331 { 1332 /* The following according to the glibc 1333 documentation. (The kernel code has non-obvious 1334 execution paths.) */ 1335 case TARGET_SIGFPE: 1336 case TARGET_SIGILL: 1337 case TARGET_SIGSEGV: 1338 case TARGET_SIGBUS: 1339 case TARGET_SIGABRT: 1340 case TARGET_SIGTRAP: 1341 case TARGET_SIGSYS: 1342 1343 case TARGET_SIGTERM: 1344 case TARGET_SIGINT: 1345 case TARGET_SIGQUIT: 1346 case TARGET_SIGKILL: 1347 case TARGET_SIGHUP: 1348 1349 case TARGET_SIGALRM: 1350 case TARGET_SIGVTALRM: 1351 case TARGET_SIGPROF: 1352 case TARGET_SIGSTOP: 1353 1354 case TARGET_SIGPIPE: 1355 case TARGET_SIGLOST: 1356 case TARGET_SIGXCPU: 1357 case TARGET_SIGXFSZ: 1358 case TARGET_SIGUSR1: 1359 case TARGET_SIGUSR2: 1360 sim_io_eprintf (CPU_STATE (current_cpu), 1361 "Exiting pid %d due to signal %d\n", 1362 pid, sig); 1363 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, 1364 NULL, pc, sim_stopped, 1365 sig == TARGET_SIGABRT 1366 ? SIM_SIGABRT : SIM_SIGILL); 1367 return 0; 1368 1369 /* The default for all other signals is to be ignored. */ 1370 default: 1371 return 0; 1372 } 1373 1374 case TARGET_SIG_IGN: 1375 switch (sig) 1376 { 1377 case TARGET_SIGKILL: 1378 case TARGET_SIGSTOP: 1379 /* Can't ignore these signals. */ 1380 sim_io_eprintf (CPU_STATE (current_cpu), 1381 "Exiting pid %d due to signal %d\n", 1382 pid, sig); 1383 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, 1384 NULL, pc, sim_stopped, SIM_SIGILL); 1385 return 0; 1386 1387 default: 1388 return 0; 1389 } 1390 break; 1391 1392 default: 1393 /* Mark the signal as pending, making schedule () check 1394 closer. The signal will be handled when the thread is 1395 scheduled and the signal is unblocked. */ 1396 current_cpu->thread_data[i].sigdata[sig].pending = 1; 1397 current_cpu->thread_data[i].sigpending = 1; 1398 return 0; 1399 } 1400 else 1401 { 1402 sim_io_eprintf (CPU_STATE (current_cpu), 1403 "Unimplemented signal: %d\n", sig); 1404 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, 1405 sim_stopped, SIM_SIGILL); 1406 } 1407 } 1408 1409 return 1410 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu)), 1411 ESRCH); 1412} 1413 1414/* Make the vector and the first item, the main thread. */ 1415 1416static void 1417make_first_thread (SIM_CPU *current_cpu) 1418{ 1419 SIM_DESC sd = CPU_STATE (current_cpu); 1420 current_cpu->thread_data 1421 = xcalloc (1, 1422 SIM_TARGET_MAX_THREADS 1423 * sizeof (current_cpu->thread_data[0])); 1424 current_cpu->thread_data[0].cpu_context 1425 = (*current_cpu->make_thread_cpu_data) (current_cpu, 1426 ¤t_cpu 1427 ->cpu_data_placeholder); 1428 current_cpu->thread_data[0].parent_threadid = -1; 1429 1430 /* For good measure. */ 1431 if (TARGET_SIG_DFL != 0) 1432 abort (); 1433} 1434 1435/* Handle unknown system calls. Returns (if it does) the syscall 1436 return value. */ 1437 1438static USI 1439cris_unknown_syscall (SIM_CPU *current_cpu, USI pc, char *s, ...) 1440{ 1441 SIM_DESC sd = CPU_STATE (current_cpu); 1442 host_callback *cb = STATE_CALLBACK (sd); 1443 1444 if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP 1445 || cris_unknown_syscall_action == CRIS_USYSC_MSG_ENOSYS) 1446 { 1447 va_list ap; 1448 1449 va_start (ap, s); 1450 sim_io_evprintf (sd, s, ap); 1451 va_end (ap); 1452 1453 if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP) 1454 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL); 1455 } 1456 1457 return -cb_host_to_target_errno (cb, ENOSYS); 1458} 1459 1460/* Main function: the handler of the "break 13" syscall insn. */ 1461 1462USI 1463cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1, 1464 USI arg2, USI arg3, USI arg4, USI arg5, USI arg6, 1465 USI pc) 1466{ 1467 CB_SYSCALL s; 1468 SIM_DESC sd = CPU_STATE (current_cpu); 1469 host_callback *cb = STATE_CALLBACK (sd); 1470 int retval; 1471 int threadno = current_cpu->threadno; 1472 1473 current_cpu->syscalls++; 1474 1475 CB_SYSCALL_INIT (&s); 1476 s.func = callnum; 1477 s.arg1 = arg1; 1478 s.arg2 = arg2; 1479 s.arg3 = arg3; 1480 1481 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need 1482 to sign-extend the lseek offset to be passed as a signed number, 1483 else we'll truncate it to something > 2GB on hosts where sizeof 1484 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is 1485 e.g. an address for some syscalls. */ 1486 if (callnum == TARGET_SYS_lseek) 1487 s.arg2 = (SI) arg2; 1488 1489 if (callnum == TARGET_SYS_exit_group 1490 || (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0)) 1491 { 1492 if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags 1493 & FLAG_CRIS_MISC_PROFILE_ALL) 1494 dump_statistics (current_cpu); 1495 sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1); 1496 } 1497 1498 s.p1 = (PTR) sd; 1499 s.p2 = (PTR) current_cpu; 1500 s.read_mem = syscall_read_mem; 1501 s.write_mem = syscall_write_mem; 1502 1503 current_cpu_for_cb_callback = current_cpu; 1504 1505 if (cb_syscall (cb, &s) != CB_RC_OK) 1506 { 1507 abort (); 1508 sim_io_eprintf (sd, "Break 13: invalid %d? Returned %ld\n", callnum, 1509 s.result); 1510 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL); 1511 } 1512 1513 retval = s.result == -1 ? -s.errcode : s.result; 1514 1515 if (s.errcode != 0 && s.errcode == cb_host_to_target_errno (cb, ENOSYS)) 1516 { 1517 /* If the generic simulator call said ENOSYS, then let's try the 1518 ones we know ourselves. 1519 1520 The convention is to provide *very limited* functionality on an 1521 as-needed basis, only what's covered by the test-suite, tests 1522 added when functionality changes and abort with a descriptive 1523 message for *everything* else. Where there's no test-case, we 1524 just abort. */ 1525 switch (callnum) 1526 { 1527 case 0: 1528 /* It's a pretty safe bet that the "old setup() system call" 1529 number will not be re-used; we can't say the same for higher 1530 numbers. We treat this simulator-generated call as "wait 1531 forever"; we re-run this insn. The wait is ended by a 1532 callback. Sanity check that this is the reason we got 1533 here. */ 1534 if (current_cpu->thread_data == NULL 1535 || (current_cpu->thread_data[threadno].pipe_write_fd == 0)) 1536 goto unimplemented_syscall; 1537 1538 sim_pc_set (current_cpu, pc); 1539 retval = arg1; 1540 break; 1541 1542 case TARGET_SYS_fcntl64: 1543 case TARGET_SYS_fcntl: 1544 switch (arg2) 1545 { 1546 case 1: 1547 /* F_GETFD. 1548 Glibc checks stdin, stdout and stderr fd:s for 1549 close-on-exec security sanity. We just need to provide a 1550 OK return value. If we really need to have a 1551 close-on-exec flag true, we could just do a real fcntl 1552 here. */ 1553 retval = 0; 1554 break; 1555 1556 case 2: 1557 /* F_SETFD. Just ignore attempts to set the close-on-exec 1558 flag. */ 1559 retval = 0; 1560 break; 1561 1562 case 3: 1563 /* F_GETFL. Check for the special case for open+fdopen. */ 1564 if (current_cpu->last_syscall == TARGET_SYS_open 1565 && arg1 == current_cpu->last_open_fd) 1566 { 1567 retval = current_cpu->last_open_flags & TARGET_O_ACCMODE; 1568 break; 1569 } 1570 else if (arg1 == 0) 1571 { 1572 /* Because we can't freopen fd:s 0, 1, 2 to mean 1573 something else than stdin, stdout and stderr 1574 (sim/common/syscall.c:cb_syscall special cases fd 1575 0, 1 and 2), we know what flags that we can 1576 sanely return for these fd:s. */ 1577 retval = TARGET_O_RDONLY; 1578 break; 1579 } 1580 else if (arg1 == 1 || arg1 == 2) 1581 { 1582 retval = TARGET_O_WRONLY; 1583 break; 1584 } 1585 /* FALLTHROUGH */ 1586 default: 1587 /* Nothing else is implemented. */ 1588 retval 1589 = cris_unknown_syscall (current_cpu, pc, 1590 "Unimplemented %s syscall " 1591 "(fd: 0x%lx: cmd: 0x%lx arg: " 1592 "0x%lx)\n", 1593 callnum == TARGET_SYS_fcntl 1594 ? "fcntl" : "fcntl64", 1595 (unsigned long) (USI) arg1, 1596 (unsigned long) (USI) arg2, 1597 (unsigned long) (USI) arg3); 1598 break; 1599 } 1600 break; 1601 1602 case TARGET_SYS_uname: 1603 { 1604 /* Fill in a few constants to appease glibc. */ 1605 static char sim_utsname[6][65] = 1606 { 1607 "Linux", 1608 "sim-target", 1609 "2.6.27", 1610 TARGET_UTSNAME, 1611 "cris", /* Overwritten below. */ 1612 "localdomain" 1613 }; 1614 1615 /* Having the hardware type in Linux equal to the bfd 1616 printable name is deliberate: if you make config.guess 1617 work on your Linux-type system the usual way, it 1618 probably will; either the bfd printable_name or the 1619 ambiguous arch_name. */ 1620 strcpy (sim_utsname[4], STATE_ARCHITECTURE (sd)->printable_name); 1621 1622 if ((s.write_mem) (cb, &s, arg1, (const char *) sim_utsname, 1623 sizeof (sim_utsname)) 1624 != sizeof (sim_utsname)) 1625 retval = -cb_host_to_target_errno (cb, EFAULT); 1626 else 1627 retval = 0; 1628 break; 1629 } 1630 1631 case TARGET_SYS_geteuid32: 1632 /* We tell the truth with these. Maybe we shouldn't, but it 1633 should match the "stat" information. */ 1634 retval = geteuid (); 1635 break; 1636 1637 case TARGET_SYS_getuid32: 1638 retval = getuid (); 1639 break; 1640 1641 case TARGET_SYS_getegid32: 1642 retval = getegid (); 1643 break; 1644 1645 case TARGET_SYS_getgid32: 1646 retval = getgid (); 1647 break; 1648 1649 case TARGET_SYS_brk: 1650 /* Most often, we just return the argument, like the Linux 1651 kernel. */ 1652 retval = arg1; 1653 1654 if (arg1 == 0) 1655 retval = current_cpu->endbrk; 1656 else if (arg1 <= current_cpu->endmem) 1657 current_cpu->endbrk = arg1; 1658 else 1659 { 1660 USI new_end = (arg1 + 8191) & ~8191; 1661 1662 /* If the simulator wants to brk more than a certain very 1663 large amount, something is wrong. FIXME: Return an error 1664 or abort? Have command-line selectable? */ 1665 if (new_end - current_cpu->endmem > SIM_MAX_ALLOC_CHUNK) 1666 { 1667 current_cpu->endbrk = current_cpu->endmem; 1668 retval = current_cpu->endmem; 1669 break; 1670 } 1671 1672 sim_core_attach (sd, NULL, 0, access_read_write_exec, 0, 1673 current_cpu->endmem, 1674 new_end - current_cpu->endmem, 1675 0, NULL, NULL); 1676 current_cpu->endbrk = arg1; 1677 current_cpu->endmem = new_end; 1678 } 1679 break; 1680 1681 case TARGET_SYS_getpid: 1682 /* Correct until CLONE_THREAD is implemented. */ 1683 retval = current_cpu->thread_data == NULL 1684 ? TARGET_PID 1685 : TARGET_PID + current_cpu->thread_data[threadno].threadid; 1686 break; 1687 1688 case TARGET_SYS_getppid: 1689 /* Correct until CLONE_THREAD is implemented. */ 1690 retval = current_cpu->thread_data == NULL 1691 ? TARGET_PID - 1 1692 : (TARGET_PID 1693 + current_cpu->thread_data[threadno].parent_threadid); 1694 break; 1695 1696 case TARGET_SYS_mmap2: 1697 { 1698 USI addr = arg1; 1699 USI len = arg2; 1700 USI prot = arg3; 1701 USI flags = arg4; 1702 USI fd = arg5; 1703 USI pgoff = arg6; 1704 1705 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls) 1706 still masked away this bit, so let's just ignore 1707 it. */ 1708 flags &= ~TARGET_MAP_DENYWRITE; 1709 1710 /* If the simulator wants to mmap more than the very large 1711 limit, something is wrong. FIXME: Return an error or 1712 abort? Have command-line selectable? */ 1713 if (len > SIM_MAX_ALLOC_CHUNK) 1714 { 1715 retval = -cb_host_to_target_errno (cb, ENOMEM); 1716 break; 1717 } 1718 1719 if ((prot != (TARGET_PROT_READ | TARGET_PROT_WRITE) 1720 && (prot 1721 != (TARGET_PROT_READ 1722 | TARGET_PROT_WRITE 1723 | TARGET_PROT_EXEC)) 1724 && (prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)) 1725 && prot != TARGET_PROT_READ) 1726 || (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE) 1727 && flags != TARGET_MAP_PRIVATE 1728 && flags != (TARGET_MAP_ANONYMOUS 1729 | TARGET_MAP_PRIVATE | TARGET_MAP_FIXED) 1730 && flags != (TARGET_MAP_PRIVATE | TARGET_MAP_FIXED) 1731 && flags != TARGET_MAP_SHARED) 1732 || (fd != (USI) -1 1733 && prot != TARGET_PROT_READ 1734 && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC) 1735 && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)) 1736 || (fd == (USI) -1 && pgoff != 0) 1737 || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS))) 1738 { 1739 retval 1740 = cris_unknown_syscall (current_cpu, pc, 1741 "Unimplemented mmap2 call " 1742 "(0x%lx, 0x%lx, 0x%lx, " 1743 "0x%lx, 0x%lx, 0x%lx)\n", 1744 (unsigned long) arg1, 1745 (unsigned long) arg2, 1746 (unsigned long) arg3, 1747 (unsigned long) arg4, 1748 (unsigned long) arg5, 1749 (unsigned long) arg6); 1750 break; 1751 } 1752 else if (fd != (USI) -1) 1753 { 1754 /* Map a file. */ 1755 1756 USI newaddr; 1757 USI pos; 1758 1759 /* A non-aligned argument is allowed for files. */ 1760 USI newlen = (len + 8191) & ~8191; 1761 1762 /* We only support read, read|exec, and read|write, 1763 which we should already have checked. Check again 1764 anyway. */ 1765 if (prot != TARGET_PROT_READ 1766 && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC) 1767 && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)) 1768 abort (); 1769 1770 if (flags & TARGET_MAP_FIXED) 1771 unmap_pages (sd, ¤t_cpu->highest_mmapped_page, 1772 addr, newlen); 1773 else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page, 1774 addr, newlen)) 1775 addr = 0; 1776 1777 newaddr 1778 = create_map (sd, ¤t_cpu->highest_mmapped_page, 1779 addr != 0 || (flags & TARGET_MAP_FIXED) 1780 ? addr : -1, 1781 newlen); 1782 1783 if (newaddr >= (USI) -8191) 1784 { 1785 abort (); 1786 retval = -cb_host_to_target_errno (cb, -(SI) newaddr); 1787 break; 1788 } 1789 1790 /* We were asked for MAP_FIXED, but couldn't. */ 1791 if ((flags & TARGET_MAP_FIXED) && newaddr != addr) 1792 { 1793 abort (); 1794 unmap_pages (sd, ¤t_cpu->highest_mmapped_page, 1795 newaddr, newlen); 1796 retval = -cb_host_to_target_errno (cb, EINVAL); 1797 break; 1798 } 1799 1800 /* Find the current position in the file. */ 1801 s.func = TARGET_SYS_lseek; 1802 s.arg1 = fd; 1803 s.arg2 = 0; 1804 s.arg3 = SEEK_CUR; 1805 if (cb_syscall (cb, &s) != CB_RC_OK) 1806 abort (); 1807 pos = s.result; 1808 1809 if (s.result < 0) 1810 abort (); 1811 1812 /* Move to the correct offset in the file. */ 1813 s.func = TARGET_SYS_lseek; 1814 s.arg1 = fd; 1815 s.arg2 = pgoff*8192; 1816 s.arg3 = SEEK_SET; 1817 if (cb_syscall (cb, &s) != CB_RC_OK) 1818 abort (); 1819 1820 if (s.result < 0) 1821 abort (); 1822 1823 /* Use the standard read callback to read in "len" 1824 bytes. */ 1825 s.func = TARGET_SYS_read; 1826 s.arg1 = fd; 1827 s.arg2 = newaddr; 1828 s.arg3 = len; 1829 if (cb_syscall (cb, &s) != CB_RC_OK) 1830 abort (); 1831 1832 /* If the result is a page or more lesser than what 1833 was requested, something went wrong. */ 1834 if (len >= 8192 && (USI) s.result <= len - 8192) 1835 abort (); 1836 1837 /* After reading, we need to go back to the previous 1838 position in the file. */ 1839 s.func = TARGET_SYS_lseek; 1840 s.arg1 = fd; 1841 s.arg2 = pos; 1842 s.arg3 = SEEK_SET; 1843 if (cb_syscall (cb, &s) != CB_RC_OK) 1844 abort (); 1845 if (pos != (USI) s.result) 1846 abort (); 1847 1848 retval = newaddr; 1849 } 1850 else 1851 { 1852 USI newlen = (len + 8191) & ~8191; 1853 USI newaddr; 1854 1855 if (flags & TARGET_MAP_FIXED) 1856 unmap_pages (sd, ¤t_cpu->highest_mmapped_page, 1857 addr, newlen); 1858 else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page, 1859 addr, newlen)) 1860 addr = 0; 1861 1862 newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page, 1863 addr != 0 || (flags & TARGET_MAP_FIXED) 1864 ? addr : -1, 1865 newlen); 1866 1867 if (newaddr >= (USI) -8191) 1868 retval = -cb_host_to_target_errno (cb, -(SI) newaddr); 1869 else 1870 retval = newaddr; 1871 1872 if ((flags & TARGET_MAP_FIXED) && newaddr != addr) 1873 { 1874 abort (); 1875 unmap_pages (sd, ¤t_cpu->highest_mmapped_page, 1876 newaddr, newlen); 1877 retval = -cb_host_to_target_errno (cb, EINVAL); 1878 break; 1879 } 1880 } 1881 break; 1882 } 1883 1884 case TARGET_SYS_mprotect: 1885 { 1886 /* We only cover the case of linuxthreads mprotecting out 1887 its stack guard page and of dynamic loading mprotecting 1888 away the data (for some reason the whole library, then 1889 mprotects away the data part and mmap-FIX:es it again. */ 1890 USI addr = arg1; 1891 USI len = arg2; 1892 USI prot = arg3; 1893 1894 if (prot != TARGET_PROT_NONE 1895 || !is_mapped_only (sd, ¤t_cpu->highest_mmapped_page, 1896 addr, (len + 8191) & ~8191)) 1897 { 1898 retval 1899 = cris_unknown_syscall (current_cpu, pc, 1900 "Unimplemented mprotect call " 1901 "(0x%lx, 0x%lx, 0x%lx)\n", 1902 (unsigned long) arg1, 1903 (unsigned long) arg2, 1904 (unsigned long) arg3); 1905 break; 1906 } 1907 1908 /* Just ignore this. We could make this equal to munmap, 1909 but then we'd have to make sure no anon mmaps gets this 1910 address before a subsequent MAP_FIXED mmap intended to 1911 override it. */ 1912 retval = 0; 1913 break; 1914 } 1915 1916 case TARGET_SYS_ioctl: 1917 { 1918 /* We support only a very limited functionality: checking 1919 stdout with TCGETS to perform the isatty function. The 1920 TCGETS ioctl isn't actually performed or the result used by 1921 an isatty () caller in a "hello, world" program; only the 1922 return value is then used. Maybe we shouldn't care about 1923 the environment of the simulator regarding isatty, but 1924 that's been working before, in the xsim simulator. */ 1925 if (arg2 == TARGET_TCGETS && arg1 == 1) 1926 retval = isatty (1) ? 0 : cb_host_to_target_errno (cb, EINVAL); 1927 else 1928 retval = -cb_host_to_target_errno (cb, EINVAL); 1929 break; 1930 } 1931 1932 case TARGET_SYS_munmap: 1933 { 1934 USI addr = arg1; 1935 USI len = arg2; 1936 USI result 1937 = unmap_pages (sd, ¤t_cpu->highest_mmapped_page, addr, 1938 len); 1939 retval = result != 0 ? -cb_host_to_target_errno (cb, result) : 0; 1940 break; 1941 } 1942 1943 case TARGET_SYS_wait4: 1944 { 1945 int i; 1946 USI pid = arg1; 1947 USI saddr = arg2; 1948 USI options = arg3; 1949 USI rusagep = arg4; 1950 1951 /* FIXME: We're not properly implementing __WCLONE, and we 1952 don't really need the special casing so we might as well 1953 make this general. */ 1954 if ((!(pid == (USI) -1 1955 && options == (TARGET___WCLONE | TARGET_WNOHANG) 1956 && saddr != 0) 1957 && !(pid > 0 1958 && (options == TARGET___WCLONE 1959 || options == TARGET___WALL))) 1960 || rusagep != 0 1961 || current_cpu->thread_data == NULL) 1962 { 1963 retval 1964 = cris_unknown_syscall (current_cpu, pc, 1965 "Unimplemented wait4 call " 1966 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", 1967 (unsigned long) arg1, 1968 (unsigned long) arg2, 1969 (unsigned long) arg3, 1970 (unsigned long) arg4); 1971 break; 1972 } 1973 1974 if (pid == (USI) -1) 1975 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++) 1976 { 1977 if (current_cpu->thread_data[threadno].threadid 1978 == current_cpu->thread_data[i].parent_threadid 1979 && current_cpu->thread_data[i].threadid != 0 1980 && current_cpu->thread_data[i].cpu_context == NULL) 1981 { 1982 /* A zombied child. Get the exit value and clear the 1983 zombied entry so it will be reused. */ 1984 sim_core_write_unaligned_4 (current_cpu, pc, 0, saddr, 1985 current_cpu 1986 ->thread_data[i].exitval); 1987 retval 1988 = current_cpu->thread_data[i].threadid + TARGET_PID; 1989 memset (¤t_cpu->thread_data[i], 0, 1990 sizeof (current_cpu->thread_data[i])); 1991 goto outer_break; 1992 } 1993 } 1994 else 1995 { 1996 /* We're waiting for a specific PID. If we don't find 1997 it zombied on this run, rerun the syscall. */ 1998 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++) 1999 if (pid == current_cpu->thread_data[i].threadid + TARGET_PID 2000 && current_cpu->thread_data[i].cpu_context == NULL) 2001 { 2002 if (saddr != 0) 2003 /* Get the exit value if the caller wants it. */ 2004 sim_core_write_unaligned_4 (current_cpu, pc, 0, 2005 saddr, 2006 current_cpu 2007 ->thread_data[i] 2008 .exitval); 2009 2010 retval 2011 = current_cpu->thread_data[i].threadid + TARGET_PID; 2012 memset (¤t_cpu->thread_data[i], 0, 2013 sizeof (current_cpu->thread_data[i])); 2014 2015 goto outer_break; 2016 } 2017 2018 sim_pc_set (current_cpu, pc); 2019 } 2020 2021 retval = -cb_host_to_target_errno (cb, ECHILD); 2022 outer_break: 2023 break; 2024 } 2025 2026 case TARGET_SYS_rt_sigaction: 2027 { 2028 USI signum = arg1; 2029 USI old_sa = arg3; 2030 USI new_sa = arg2; 2031 2032 /* The kernel says: 2033 struct sigaction { 2034 __sighandler_t sa_handler; 2035 unsigned long sa_flags; 2036 void (*sa_restorer)(void); 2037 sigset_t sa_mask; 2038 }; */ 2039 2040 if (old_sa != 0) 2041 { 2042 sim_core_write_unaligned_4 (current_cpu, pc, 0, old_sa + 0, 2043 current_cpu->sighandler[signum]); 2044 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 4, 0); 2045 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 8, 0); 2046 2047 /* We'll assume _NSIG_WORDS is 2 for the kernel. */ 2048 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 12, 0); 2049 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 16, 0); 2050 } 2051 if (new_sa != 0) 2052 { 2053 USI target_sa_handler 2054 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa); 2055 USI target_sa_flags 2056 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 4); 2057 USI target_sa_restorer 2058 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 8); 2059 USI target_sa_mask_low 2060 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 12); 2061 USI target_sa_mask_high 2062 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 16); 2063 2064 /* We won't interrupt a syscall so we won't restart it, 2065 but a signal(2) call ends up syscalling rt_sigaction 2066 with this flag, so we have to handle it. The 2067 sa_restorer field contains garbage when not 2068 TARGET_SA_RESTORER, so don't look at it. For the 2069 time being, we don't nest sighandlers, so we 2070 ignore the sa_mask, which simplifies things. */ 2071 if ((target_sa_flags != 0 2072 && target_sa_flags != TARGET_SA_RESTART 2073 && target_sa_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO)) 2074 || target_sa_handler == 0) 2075 { 2076 retval 2077 = cris_unknown_syscall (current_cpu, pc, 2078 "Unimplemented rt_sigaction " 2079 "syscall " 2080 "(0x%lx, 0x%lx: " 2081 "[0x%x, 0x%x, 0x%x, " 2082 "{0x%x, 0x%x}], 0x%lx)\n", 2083 (unsigned long) arg1, 2084 (unsigned long) arg2, 2085 target_sa_handler, 2086 target_sa_flags, 2087 target_sa_restorer, 2088 target_sa_mask_low, 2089 target_sa_mask_high, 2090 (unsigned long) arg3); 2091 break; 2092 } 2093 2094 current_cpu->sighandler[signum] = target_sa_handler; 2095 2096 /* Because we may have unblocked signals, one may now be 2097 pending, if there are threads, that is. */ 2098 if (current_cpu->thread_data) 2099 current_cpu->thread_data[threadno].sigpending = 1; 2100 } 2101 retval = 0; 2102 break; 2103 } 2104 2105 case TARGET_SYS_mremap: 2106 { 2107 USI addr = arg1; 2108 USI old_len = arg2; 2109 USI new_len = arg3; 2110 USI flags = arg4; 2111 USI new_addr = arg5; 2112 USI mapped_addr; 2113 2114 if (new_len == old_len) 2115 /* The program and/or library is possibly confused but 2116 this is a valid call. Happens with ipps-1.40 on file 2117 svs_all. */ 2118 retval = addr; 2119 else if (new_len < old_len) 2120 { 2121 /* Shrinking is easy. */ 2122 if (unmap_pages (sd, ¤t_cpu->highest_mmapped_page, 2123 addr + new_len, old_len - new_len) != 0) 2124 retval = -cb_host_to_target_errno (cb, EINVAL); 2125 else 2126 retval = addr; 2127 } 2128 else if (! is_mapped (sd, ¤t_cpu->highest_mmapped_page, 2129 addr + old_len, new_len - old_len)) 2130 { 2131 /* If the extension isn't mapped, we can just add it. */ 2132 mapped_addr 2133 = create_map (sd, ¤t_cpu->highest_mmapped_page, 2134 addr + old_len, new_len - old_len); 2135 2136 if (mapped_addr > (USI) -8192) 2137 retval = -cb_host_to_target_errno (cb, -(SI) mapped_addr); 2138 else 2139 retval = addr; 2140 } 2141 else if (flags & TARGET_MREMAP_MAYMOVE) 2142 { 2143 /* Create a whole new map and copy the contents 2144 block-by-block there. We ignore the new_addr argument 2145 for now. */ 2146 char buf[8192]; 2147 USI prev_addr = addr; 2148 USI prev_len = old_len; 2149 2150 mapped_addr 2151 = create_map (sd, ¤t_cpu->highest_mmapped_page, 2152 -1, new_len); 2153 2154 if (mapped_addr > (USI) -8192) 2155 { 2156 retval = -cb_host_to_target_errno (cb, -(SI) new_addr); 2157 break; 2158 } 2159 2160 retval = mapped_addr; 2161 2162 for (; old_len > 0; 2163 old_len -= 8192, mapped_addr += 8192, addr += 8192) 2164 { 2165 if (sim_core_read_buffer (sd, current_cpu, read_map, buf, 2166 addr, 8192) != 8192 2167 || sim_core_write_buffer (sd, current_cpu, 0, buf, 2168 mapped_addr, 8192) != 8192) 2169 abort (); 2170 } 2171 2172 if (unmap_pages (sd, ¤t_cpu->highest_mmapped_page, 2173 prev_addr, prev_len) != 0) 2174 abort (); 2175 } 2176 else 2177 retval = -cb_host_to_target_errno (cb, -ENOMEM); 2178 break; 2179 } 2180 2181 case TARGET_SYS_poll: 2182 { 2183 int npollfds = arg2; 2184 int timeout = arg3; 2185 SI ufds = arg1; 2186 SI fd = -1; 2187 HI events = -1; 2188 HI revents = 0; 2189 struct stat buf; 2190 int i; 2191 2192 /* The kernel says: 2193 struct pollfd { 2194 int fd; 2195 short events; 2196 short revents; 2197 }; */ 2198 2199 /* Check that this is the expected poll call from 2200 linuxthreads/manager.c; we don't support anything else. 2201 Remember, fd == 0 isn't supported. */ 2202 if (npollfds != 1 2203 || ((fd = sim_core_read_unaligned_4 (current_cpu, pc, 2204 0, ufds)) <= 0) 2205 || ((events = sim_core_read_unaligned_2 (current_cpu, pc, 2206 0, ufds + 4)) 2207 != TARGET_POLLIN) 2208 || ((cb->fstat) (cb, fd, &buf) != 0 2209 || (buf.st_mode & S_IFIFO) == 0) 2210 || current_cpu->thread_data == NULL) 2211 { 2212 retval 2213 = cris_unknown_syscall (current_cpu, pc, 2214 "Unimplemented poll syscall " 2215 "(0x%lx: [0x%x, 0x%x, x], " 2216 "0x%lx, 0x%lx)\n", 2217 (unsigned long) arg1, fd, events, 2218 (unsigned long) arg2, 2219 (unsigned long) arg3); 2220 break; 2221 } 2222 2223 retval = 0; 2224 2225 /* Iterate over threads; find a marker that a writer is 2226 sleeping, waiting for a reader. */ 2227 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++) 2228 if (current_cpu->thread_data[i].cpu_context != NULL 2229 && current_cpu->thread_data[i].pipe_read_fd == fd) 2230 { 2231 revents = TARGET_POLLIN; 2232 retval = 1; 2233 break; 2234 } 2235 2236 /* Timeout decreases with whatever time passed between the 2237 last syscall and this. That's not exactly right for the 2238 first call, but it's close enough that it isn't 2239 worthwhile to complicate matters by making that a special 2240 case. */ 2241 timeout 2242 -= (TARGET_TIME_MS (current_cpu) 2243 - (current_cpu->thread_data[threadno].last_execution)); 2244 2245 /* Arrange to repeat this syscall until timeout or event, 2246 decreasing timeout at each iteration. */ 2247 if (timeout > 0 && revents == 0) 2248 { 2249 bfd_byte timeout_buf[4]; 2250 2251 bfd_putl32 (timeout, timeout_buf); 2252 (*CPU_REG_STORE (current_cpu)) (current_cpu, 2253 H_GR_R12, timeout_buf, 4); 2254 sim_pc_set (current_cpu, pc); 2255 retval = arg1; 2256 break; 2257 } 2258 2259 sim_core_write_unaligned_2 (current_cpu, pc, 0, ufds + 4 + 2, 2260 revents); 2261 break; 2262 } 2263 2264 case TARGET_SYS_time: 2265 { 2266 retval = (int) (*cb->time) (cb, 0L); 2267 2268 /* At time of this writing, CB_SYSCALL_time doesn't do the 2269 part of setting *arg1 to the return value. */ 2270 if (arg1) 2271 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, retval); 2272 break; 2273 } 2274 2275 case TARGET_SYS_gettimeofday: 2276 if (arg1 != 0) 2277 { 2278 USI ts = TARGET_TIME (current_cpu); 2279 USI tms = TARGET_TIME_MS (current_cpu); 2280 2281 /* First dword is seconds since TARGET_EPOCH. */ 2282 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, ts); 2283 2284 /* Second dword is microseconds. */ 2285 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1 + 4, 2286 (tms % 1000) * 1000); 2287 } 2288 if (arg2 != 0) 2289 { 2290 /* Time-zone info is always cleared. */ 2291 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, 0); 2292 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, 0); 2293 } 2294 retval = 0; 2295 break; 2296 2297 case TARGET_SYS_llseek: 2298 { 2299 /* If it fits, tweak parameters to fit the "generic" 32-bit 2300 lseek and use that. */ 2301 SI fd = arg1; 2302 SI offs_hi = arg2; 2303 SI offs_lo = arg3; 2304 SI resultp = arg4; 2305 SI whence = arg5; 2306 retval = 0; 2307 2308 if (!((offs_hi == 0 && offs_lo >= 0) 2309 || (offs_hi == -1 && offs_lo < 0))) 2310 { 2311 retval 2312 = cris_unknown_syscall (current_cpu, pc, 2313 "Unimplemented llseek offset," 2314 " fd %d: 0x%x:0x%x\n", 2315 fd, (unsigned) arg2, 2316 (unsigned) arg3); 2317 break; 2318 } 2319 2320 s.func = TARGET_SYS_lseek; 2321 s.arg2 = offs_lo; 2322 s.arg3 = whence; 2323 if (cb_syscall (cb, &s) != CB_RC_OK) 2324 { 2325 sim_io_eprintf (sd, "Break 13: invalid %d? Returned %ld\n", callnum, 2326 s.result); 2327 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL); 2328 } 2329 if (s.result < 0) 2330 retval = -s.errcode; 2331 else 2332 { 2333 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp, 2334 s.result); 2335 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp + 4, 2336 s.result < 0 ? -1 : 0); 2337 } 2338 break; 2339 } 2340 2341 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt); 2342 where: 2343 struct iovec { 2344 void *iov_base; Starting address 2345 size_t iov_len; Number of bytes to transfer 2346 }; */ 2347 case TARGET_SYS_writev: 2348 { 2349 SI fd = arg1; 2350 SI iov = arg2; 2351 SI iovcnt = arg3; 2352 SI retcnt = 0; 2353 int i; 2354 2355 /* We'll ignore strict error-handling and just do multiple write calls. */ 2356 for (i = 0; i < iovcnt; i++) 2357 { 2358 int sysret; 2359 USI iov_base 2360 = sim_core_read_unaligned_4 (current_cpu, pc, 0, 2361 iov + 8*i); 2362 USI iov_len 2363 = sim_core_read_unaligned_4 (current_cpu, pc, 0, 2364 iov + 8*i + 4); 2365 2366 s.func = TARGET_SYS_write; 2367 s.arg1 = fd; 2368 s.arg2 = iov_base; 2369 s.arg3 = iov_len; 2370 2371 if (cb_syscall (cb, &s) != CB_RC_OK) 2372 abort (); 2373 sysret = s.result == -1 ? -s.errcode : s.result; 2374 2375 if (sysret != iov_len) 2376 { 2377 if (i != 0) 2378 abort (); 2379 retcnt = sysret; 2380 break; 2381 } 2382 2383 retcnt += iov_len; 2384 } 2385 2386 retval = retcnt; 2387 } 2388 break; 2389 2390 /* This one does have a generic callback function, but at the time 2391 of this writing, cb_syscall does not have code for it, and we 2392 need target-specific code for the threads implementation 2393 anyway. */ 2394 case TARGET_SYS_kill: 2395 { 2396 USI pid = arg1; 2397 USI sig = arg2; 2398 2399 retval = 0; 2400 2401 /* At kill(2), glibc sets signal masks such that the thread 2402 machinery is initialized. Still, there is and was only 2403 one thread. */ 2404 if (current_cpu->max_threadid == 0) 2405 { 2406 if (pid != TARGET_PID) 2407 { 2408 retval = -cb_host_to_target_errno (cb, EPERM); 2409 break; 2410 } 2411 2412 /* FIXME: Signal infrastructure (target-to-sim mapping). */ 2413 if (sig == TARGET_SIGABRT) 2414 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is 2415 the end-point for failing GCC test-cases. */ 2416 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, 2417 SIM_SIGABRT); 2418 else 2419 { 2420 sim_io_eprintf (sd, "Unimplemented signal: %d\n", sig); 2421 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, 2422 SIM_SIGILL); 2423 } 2424 2425 /* This will not be reached. */ 2426 abort (); 2427 } 2428 else 2429 retval = deliver_signal (current_cpu, sig, pid); 2430 break; 2431 } 2432 2433 case TARGET_SYS_rt_sigprocmask: 2434 { 2435 int i; 2436 USI how = arg1; 2437 USI newsetp = arg2; 2438 USI oldsetp = arg3; 2439 2440 if (how != TARGET_SIG_BLOCK 2441 && how != TARGET_SIG_SETMASK 2442 && how != TARGET_SIG_UNBLOCK) 2443 { 2444 retval 2445 = cris_unknown_syscall (current_cpu, pc, 2446 "Unimplemented rt_sigprocmask " 2447 "syscall (0x%x, 0x%x, 0x%x)\n", 2448 arg1, arg2, arg3); 2449 break; 2450 } 2451 2452 if (newsetp) 2453 { 2454 USI set_low 2455 = sim_core_read_unaligned_4 (current_cpu, pc, 0, 2456 newsetp); 2457 USI set_high 2458 = sim_core_read_unaligned_4 (current_cpu, pc, 0, 2459 newsetp + 4); 2460 2461 /* The sigmask is kept in the per-thread data, so we may 2462 need to create the first one. */ 2463 if (current_cpu->thread_data == NULL) 2464 make_first_thread (current_cpu); 2465 2466 if (how == TARGET_SIG_SETMASK) 2467 for (i = 0; i < 64; i++) 2468 current_cpu->thread_data[threadno].sigdata[i].blocked = 0; 2469 2470 for (i = 0; i < 32; i++) 2471 if ((set_low & (1 << i))) 2472 current_cpu->thread_data[threadno].sigdata[i + 1].blocked 2473 = (how != TARGET_SIG_UNBLOCK); 2474 2475 for (i = 0; i < 31; i++) 2476 if ((set_high & (1 << i))) 2477 current_cpu->thread_data[threadno].sigdata[i + 33].blocked 2478 = (how != TARGET_SIG_UNBLOCK); 2479 2480 /* The mask changed, so a signal may be unblocked for 2481 execution. */ 2482 current_cpu->thread_data[threadno].sigpending = 1; 2483 } 2484 2485 if (oldsetp != 0) 2486 { 2487 USI set_low = 0; 2488 USI set_high = 0; 2489 2490 for (i = 0; i < 32; i++) 2491 if (current_cpu->thread_data[threadno] 2492 .sigdata[i + 1].blocked) 2493 set_low |= 1 << i; 2494 for (i = 0; i < 31; i++) 2495 if (current_cpu->thread_data[threadno] 2496 .sigdata[i + 33].blocked) 2497 set_high |= 1 << i; 2498 2499 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 0, set_low); 2500 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 4, set_high); 2501 } 2502 2503 retval = 0; 2504 break; 2505 } 2506 2507 case TARGET_SYS_sigreturn: 2508 { 2509 int i; 2510 bfd_byte regbuf[4]; 2511 int was_sigsuspended; 2512 2513 if (current_cpu->thread_data == NULL 2514 /* The CPU context is saved with the simulator data, not 2515 on the stack as in the real world. */ 2516 || (current_cpu->thread_data[threadno].cpu_context_atsignal 2517 == NULL)) 2518 { 2519 retval 2520 = cris_unknown_syscall (current_cpu, pc, 2521 "Invalid sigreturn syscall: " 2522 "no signal handler active " 2523 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, " 2524 "0x%lx, 0x%lx)\n", 2525 (unsigned long) arg1, 2526 (unsigned long) arg2, 2527 (unsigned long) arg3, 2528 (unsigned long) arg4, 2529 (unsigned long) arg5, 2530 (unsigned long) arg6); 2531 break; 2532 } 2533 2534 was_sigsuspended 2535 = current_cpu->thread_data[threadno].sigsuspended; 2536 2537 /* Restore the sigmask, either from the stack copy made when 2538 the sighandler was called, or from the saved state 2539 specifically for sigsuspend(2). */ 2540 if (was_sigsuspended) 2541 { 2542 current_cpu->thread_data[threadno].sigsuspended = 0; 2543 for (i = 0; i < 64; i++) 2544 current_cpu->thread_data[threadno].sigdata[i].blocked 2545 = current_cpu->thread_data[threadno] 2546 .sigdata[i].blocked_suspendsave; 2547 } 2548 else 2549 { 2550 USI sp; 2551 USI set_low; 2552 USI set_high; 2553 2554 (*CPU_REG_FETCH (current_cpu)) (current_cpu, 2555 H_GR_SP, regbuf, 4); 2556 sp = bfd_getl32 (regbuf); 2557 set_low 2558 = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp); 2559 set_high 2560 = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp + 4); 2561 2562 for (i = 0; i < 32; i++) 2563 current_cpu->thread_data[threadno].sigdata[i + 1].blocked 2564 = (set_low & (1 << i)) != 0; 2565 for (i = 0; i < 31; i++) 2566 current_cpu->thread_data[threadno].sigdata[i + 33].blocked 2567 = (set_high & (1 << i)) != 0; 2568 } 2569 2570 /* The mask changed, so a signal may be unblocked for 2571 execution. */ 2572 current_cpu->thread_data[threadno].sigpending = 1; 2573 2574 memcpy (¤t_cpu->cpu_data_placeholder, 2575 current_cpu->thread_data[threadno].cpu_context_atsignal, 2576 current_cpu->thread_cpu_data_size); 2577 free (current_cpu->thread_data[threadno].cpu_context_atsignal); 2578 current_cpu->thread_data[threadno].cpu_context_atsignal = NULL; 2579 2580 /* The return value must come from the saved R10. */ 2581 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, regbuf, 4); 2582 retval = bfd_getl32 (regbuf); 2583 2584 /* We must also break the "sigsuspension loop". */ 2585 if (was_sigsuspended) 2586 sim_pc_set (current_cpu, sim_pc_get (current_cpu) + 2); 2587 break; 2588 } 2589 2590 case TARGET_SYS_rt_sigsuspend: 2591 { 2592 USI newsetp = arg1; 2593 USI setsize = arg2; 2594 2595 if (setsize != 8) 2596 { 2597 retval 2598 = cris_unknown_syscall (current_cpu, pc, 2599 "Unimplemented rt_sigsuspend syscall" 2600 " arguments (0x%lx, 0x%lx)\n", 2601 (unsigned long) arg1, 2602 (unsigned long) arg2); 2603 break; 2604 } 2605 2606 /* Don't change the signal mask if we're already in 2607 sigsuspend state (i.e. this syscall is a rerun). */ 2608 else if (!current_cpu->thread_data[threadno].sigsuspended) 2609 { 2610 USI set_low 2611 = sim_core_read_unaligned_4 (current_cpu, pc, 0, 2612 newsetp); 2613 USI set_high 2614 = sim_core_read_unaligned_4 (current_cpu, pc, 0, 2615 newsetp + 4); 2616 int i; 2617 2618 /* Save the current sigmask and insert the user-supplied 2619 one. */ 2620 for (i = 0; i < 32; i++) 2621 { 2622 current_cpu->thread_data[threadno] 2623 .sigdata[i + 1].blocked_suspendsave 2624 = current_cpu->thread_data[threadno] 2625 .sigdata[i + 1].blocked; 2626 2627 current_cpu->thread_data[threadno] 2628 .sigdata[i + 1].blocked = (set_low & (1 << i)) != 0; 2629 } 2630 for (i = 0; i < 31; i++) 2631 { 2632 current_cpu->thread_data[threadno] 2633 .sigdata[i + 33].blocked_suspendsave 2634 = current_cpu->thread_data[threadno] 2635 .sigdata[i + 33].blocked; 2636 current_cpu->thread_data[threadno] 2637 .sigdata[i + 33].blocked = (set_high & (1 << i)) != 0; 2638 } 2639 2640 current_cpu->thread_data[threadno].sigsuspended = 1; 2641 2642 /* The mask changed, so a signal may be unblocked for 2643 execution. */ 2644 current_cpu->thread_data[threadno].sigpending = 1; 2645 } 2646 2647 /* Because we don't use arg1 (newsetp) when this syscall is 2648 rerun, it doesn't matter that we overwrite it with the 2649 (constant) return value. */ 2650 retval = -cb_host_to_target_errno (cb, EINTR); 2651 sim_pc_set (current_cpu, pc); 2652 break; 2653 } 2654 2655 /* Add case labels here for other syscalls using the 32-bit 2656 "struct stat", provided they have a corresponding simulator 2657 function of course. */ 2658 case TARGET_SYS_stat: 2659 case TARGET_SYS_fstat: 2660 { 2661 /* As long as the infrastructure doesn't cache anything 2662 related to the stat mapping, this trick gets us a dual 2663 "struct stat"-type mapping in the least error-prone way. */ 2664 const char *saved_map = cb->stat_map; 2665 CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map; 2666 2667 cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_stat32_map; 2668 cb->stat_map = stat32_map; 2669 2670 if (cb_syscall (cb, &s) != CB_RC_OK) 2671 { 2672 abort (); 2673 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, 2674 SIM_SIGILL); 2675 } 2676 retval = s.result == -1 ? -s.errcode : s.result; 2677 2678 cb->stat_map = saved_map; 2679 cb->syscall_map = saved_syscall_map; 2680 break; 2681 } 2682 2683 case TARGET_SYS_getcwd: 2684 { 2685 USI buf = arg1; 2686 USI size = arg2; 2687 2688 char *cwd = xmalloc (SIM_PATHMAX); 2689 if (cwd != getcwd (cwd, SIM_PATHMAX)) 2690 abort (); 2691 2692 /* FIXME: When and if we support chdir, we need something 2693 a bit more elaborate. */ 2694 if (simulator_sysroot[0] != '\0') 2695 strcpy (cwd, "/"); 2696 2697 retval = -cb_host_to_target_errno (cb, ERANGE); 2698 if (strlen (cwd) + 1 <= size) 2699 { 2700 retval = strlen (cwd) + 1; 2701 if (sim_core_write_buffer (sd, current_cpu, 0, cwd, 2702 buf, retval) 2703 != (unsigned int) retval) 2704 retval = -cb_host_to_target_errno (cb, EFAULT); 2705 } 2706 free (cwd); 2707 break; 2708 } 2709 2710 case TARGET_SYS_access: 2711 { 2712 SI path = arg1; 2713 SI mode = arg2; 2714 char *pbuf = xmalloc (SIM_PATHMAX); 2715 int i; 2716 int o = 0; 2717 int hmode = 0; 2718 2719 if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/') 2720 { 2721 strcpy (pbuf, simulator_sysroot); 2722 o += strlen (simulator_sysroot); 2723 } 2724 2725 for (i = 0; i + o < SIM_PATHMAX; i++) 2726 { 2727 pbuf[i + o] 2728 = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i); 2729 if (pbuf[i + o] == 0) 2730 break; 2731 } 2732 2733 if (i + o == SIM_PATHMAX) 2734 { 2735 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG); 2736 break; 2737 } 2738 2739 /* Assert that we don't get calls for files for which we 2740 don't have support. */ 2741 if (strncmp (pbuf + strlen (simulator_sysroot), 2742 "/proc/", 6) == 0) 2743 abort (); 2744#define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x 2745 X_AFLAG (R_OK); 2746 X_AFLAG (W_OK); 2747 X_AFLAG (X_OK); 2748 X_AFLAG (F_OK); 2749#undef X_AFLAG 2750 2751 if (access (pbuf, hmode) != 0) 2752 retval = -cb_host_to_target_errno (cb, errno); 2753 else 2754 retval = 0; 2755 2756 free (pbuf); 2757 break; 2758 } 2759 2760 case TARGET_SYS_readlink: 2761 { 2762 SI path = arg1; 2763 SI buf = arg2; 2764 SI bufsiz = arg3; 2765 char *pbuf = xmalloc (SIM_PATHMAX); 2766 char *lbuf = xmalloc (SIM_PATHMAX); 2767 char *lbuf_alloc = lbuf; 2768 int nchars = -1; 2769 int i; 2770 int o = 0; 2771 2772 if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/') 2773 { 2774 strcpy (pbuf, simulator_sysroot); 2775 o += strlen (simulator_sysroot); 2776 } 2777 2778 for (i = 0; i + o < SIM_PATHMAX; i++) 2779 { 2780 pbuf[i + o] 2781 = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i); 2782 if (pbuf[i + o] == 0) 2783 break; 2784 } 2785 2786 if (i + o == SIM_PATHMAX) 2787 { 2788 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG); 2789 break; 2790 } 2791 2792 /* Intervene calls for certain files expected in the target 2793 proc file system. */ 2794 if (strcmp (pbuf + strlen (simulator_sysroot), 2795 "/proc/" XSTRING (TARGET_PID) "/exe") == 0) 2796 { 2797 char *argv0 2798 = (STATE_PROG_ARGV (sd) != NULL 2799 ? *STATE_PROG_ARGV (sd) : NULL); 2800 2801 if (argv0 == NULL || *argv0 == '.') 2802 { 2803 retval 2804 = cris_unknown_syscall (current_cpu, pc, 2805 "Unimplemented readlink syscall " 2806 "(0x%lx: [\"%s\"], 0x%lx)\n", 2807 (unsigned long) arg1, pbuf, 2808 (unsigned long) arg2); 2809 break; 2810 } 2811 else if (*argv0 == '/') 2812 { 2813 if (strncmp (simulator_sysroot, argv0, 2814 strlen (simulator_sysroot)) == 0) 2815 argv0 += strlen (simulator_sysroot); 2816 2817 strcpy (lbuf, argv0); 2818 nchars = strlen (argv0) + 1; 2819 } 2820 else 2821 { 2822 if (getcwd (lbuf, SIM_PATHMAX) != NULL 2823 && strlen (lbuf) + 2 + strlen (argv0) < SIM_PATHMAX) 2824 { 2825 if (strncmp (simulator_sysroot, lbuf, 2826 strlen (simulator_sysroot)) == 0) 2827 lbuf += strlen (simulator_sysroot); 2828 2829 strcat (lbuf, "/"); 2830 strcat (lbuf, argv0); 2831 nchars = strlen (lbuf) + 1; 2832 } 2833 else 2834 abort (); 2835 } 2836 } 2837 else 2838 nchars = readlink (pbuf, lbuf, SIM_PATHMAX); 2839 2840 /* We trust that the readlink result returns a *relative* 2841 link, or one already adjusted for the file-path-prefix. 2842 (We can't generally tell the difference, so we go with 2843 the easiest decision; no adjustment.) */ 2844 2845 if (nchars == -1) 2846 { 2847 retval = -cb_host_to_target_errno (cb, errno); 2848 break; 2849 } 2850 2851 if (bufsiz < nchars) 2852 nchars = bufsiz; 2853 2854 if (sim_core_write_buffer (sd, current_cpu, write_map, lbuf, 2855 buf, nchars) != (unsigned int) nchars) 2856 retval = -cb_host_to_target_errno (cb, EFAULT); 2857 else 2858 retval = nchars; 2859 2860 free (pbuf); 2861 free (lbuf_alloc); 2862 break; 2863 } 2864 2865 case TARGET_SYS_sched_getscheduler: 2866 { 2867 USI pid = arg1; 2868 2869 /* FIXME: Search (other) existing threads. */ 2870 if (pid != 0 && pid != TARGET_PID) 2871 retval = -cb_host_to_target_errno (cb, ESRCH); 2872 else 2873 retval = TARGET_SCHED_OTHER; 2874 break; 2875 } 2876 2877 case TARGET_SYS_sched_getparam: 2878 { 2879 USI pid = arg1; 2880 USI paramp = arg2; 2881 2882 /* The kernel says: 2883 struct sched_param { 2884 int sched_priority; 2885 }; */ 2886 2887 if (pid != 0 && pid != TARGET_PID) 2888 retval = -cb_host_to_target_errno (cb, ESRCH); 2889 else 2890 { 2891 /* FIXME: Save scheduler setting before threads are 2892 created too. */ 2893 sim_core_write_unaligned_4 (current_cpu, pc, 0, paramp, 2894 current_cpu->thread_data != NULL 2895 ? (current_cpu 2896 ->thread_data[threadno] 2897 .priority) 2898 : 0); 2899 retval = 0; 2900 } 2901 break; 2902 } 2903 2904 case TARGET_SYS_sched_setparam: 2905 { 2906 USI pid = arg1; 2907 USI paramp = arg2; 2908 2909 if ((pid != 0 && pid != TARGET_PID) 2910 || sim_core_read_unaligned_4 (current_cpu, pc, 0, 2911 paramp) != 0) 2912 retval = -cb_host_to_target_errno (cb, EINVAL); 2913 else 2914 retval = 0; 2915 break; 2916 } 2917 2918 case TARGET_SYS_sched_setscheduler: 2919 { 2920 USI pid = arg1; 2921 USI policy = arg2; 2922 USI paramp = arg3; 2923 2924 if ((pid != 0 && pid != TARGET_PID) 2925 || policy != TARGET_SCHED_OTHER 2926 || sim_core_read_unaligned_4 (current_cpu, pc, 0, 2927 paramp) != 0) 2928 retval = -cb_host_to_target_errno (cb, EINVAL); 2929 else 2930 /* FIXME: Save scheduler setting to be read in later 2931 sched_getparam calls. */ 2932 retval = 0; 2933 break; 2934 } 2935 2936 case TARGET_SYS_sched_yield: 2937 /* We reschedule to the next thread after a syscall anyway, so 2938 we don't have to do anything here than to set the return 2939 value. */ 2940 retval = 0; 2941 break; 2942 2943 case TARGET_SYS_sched_get_priority_min: 2944 case TARGET_SYS_sched_get_priority_max: 2945 if (arg1 != 0) 2946 retval = -cb_host_to_target_errno (cb, EINVAL); 2947 else 2948 retval = 0; 2949 break; 2950 2951 case TARGET_SYS_ugetrlimit: 2952 { 2953 unsigned int curlim, maxlim; 2954 if (arg1 != TARGET_RLIMIT_STACK && arg1 != TARGET_RLIMIT_NOFILE) 2955 { 2956 retval = -cb_host_to_target_errno (cb, EINVAL); 2957 break; 2958 } 2959 2960 /* The kernel says: 2961 struct rlimit { 2962 unsigned long rlim_cur; 2963 unsigned long rlim_max; 2964 }; */ 2965 if (arg1 == TARGET_RLIMIT_NOFILE) 2966 { 2967 /* Sadly a very low limit. Better not lie, though. */ 2968 maxlim = curlim = MAX_CALLBACK_FDS; 2969 } 2970 else /* arg1 == TARGET_RLIMIT_STACK */ 2971 { 2972 maxlim = 0xffffffff; 2973 curlim = 0x800000; 2974 } 2975 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, curlim); 2976 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, maxlim); 2977 retval = 0; 2978 break; 2979 } 2980 2981 case TARGET_SYS_setrlimit: 2982 if (arg1 != TARGET_RLIMIT_STACK) 2983 { 2984 retval = -cb_host_to_target_errno (cb, EINVAL); 2985 break; 2986 } 2987 /* FIXME: Save values for future ugetrlimit calls. */ 2988 retval = 0; 2989 break; 2990 2991 /* Provide a very limited subset of the sysctl functions, and 2992 abort for the rest. */ 2993 case TARGET_SYS__sysctl: 2994 { 2995 /* The kernel says: 2996 struct __sysctl_args { 2997 int *name; 2998 int nlen; 2999 void *oldval; 3000 size_t *oldlenp; 3001 void *newval; 3002 size_t newlen; 3003 unsigned long __unused[4]; 3004 }; */ 3005 SI name = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1); 3006 SI name0 = name == 0 3007 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name); 3008 SI name1 = name == 0 3009 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name + 4); 3010 SI nlen 3011 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 4); 3012 SI oldval 3013 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 8); 3014 SI oldlenp 3015 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 12); 3016 SI oldlen = oldlenp == 0 3017 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, oldlenp); 3018 SI newval 3019 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 16); 3020 SI newlen 3021 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 20); 3022 3023 if (name0 == TARGET_CTL_KERN && name1 == TARGET_CTL_KERN_VERSION) 3024 { 3025 SI to_write = oldlen < (SI) sizeof (TARGET_UTSNAME) 3026 ? oldlen : (SI) sizeof (TARGET_UTSNAME); 3027 3028 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldlenp, 3029 sizeof (TARGET_UTSNAME)); 3030 3031 if (sim_core_write_buffer (sd, current_cpu, write_map, 3032 TARGET_UTSNAME, oldval, 3033 to_write) 3034 != (unsigned int) to_write) 3035 retval = -cb_host_to_target_errno (cb, EFAULT); 3036 else 3037 retval = 0; 3038 break; 3039 } 3040 3041 retval 3042 = cris_unknown_syscall (current_cpu, pc, 3043 "Unimplemented _sysctl syscall " 3044 "(0x%lx: [0x%lx, 0x%lx]," 3045 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", 3046 (unsigned long) name, 3047 (unsigned long) name0, 3048 (unsigned long) name1, 3049 (unsigned long) nlen, 3050 (unsigned long) oldval, 3051 (unsigned long) oldlenp, 3052 (unsigned long) newval, 3053 (unsigned long) newlen); 3054 break; 3055 } 3056 3057 case TARGET_SYS_exit: 3058 { 3059 /* Here for all but the last thread. */ 3060 int i; 3061 int pid 3062 = current_cpu->thread_data[threadno].threadid + TARGET_PID; 3063 int ppid 3064 = (current_cpu->thread_data[threadno].parent_threadid 3065 + TARGET_PID); 3066 int exitsig = current_cpu->thread_data[threadno].exitsig; 3067 3068 /* Any children are now all orphans. */ 3069 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++) 3070 if (current_cpu->thread_data[i].parent_threadid 3071 == current_cpu->thread_data[threadno].threadid) 3072 /* Make getppid(2) return 1 for them, poor little ones. */ 3073 current_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1; 3074 3075 /* Free the cpu context data. When the parent has received 3076 the exit status, we'll clear the entry too. */ 3077 free (current_cpu->thread_data[threadno].cpu_context); 3078 current_cpu->thread_data[threadno].cpu_context = NULL; 3079 current_cpu->m1threads--; 3080 if (arg1 != 0) 3081 { 3082 sim_io_eprintf (sd, "Thread %d exited with status %d\n", 3083 pid, arg1); 3084 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, 3085 SIM_SIGILL); 3086 } 3087 3088 /* Still, we may want to support non-zero exit values. */ 3089 current_cpu->thread_data[threadno].exitval = arg1 << 8; 3090 3091 if (exitsig) 3092 deliver_signal (current_cpu, exitsig, ppid); 3093 break; 3094 } 3095 3096 case TARGET_SYS_clone: 3097 { 3098 int nthreads = current_cpu->m1threads + 1; 3099 void *thread_cpu_data; 3100 bfd_byte old_sp_buf[4]; 3101 bfd_byte sp_buf[4]; 3102 const bfd_byte zeros[4] = { 0, 0, 0, 0 }; 3103 int i; 3104 3105 /* That's right, the syscall clone arguments are reversed 3106 compared to sys_clone notes in clone(2) and compared to 3107 other Linux ports (i.e. it's the same order as in the 3108 clone(2) libcall). */ 3109 USI flags = arg2; 3110 USI newsp = arg1; 3111 3112 if (nthreads == SIM_TARGET_MAX_THREADS) 3113 { 3114 retval = -cb_host_to_target_errno (cb, EAGAIN); 3115 break; 3116 } 3117 3118 /* FIXME: Implement the low byte. */ 3119 if ((flags & ~TARGET_CSIGNAL) != 3120 (TARGET_CLONE_VM 3121 | TARGET_CLONE_FS 3122 | TARGET_CLONE_FILES 3123 | TARGET_CLONE_SIGHAND) 3124 || newsp == 0) 3125 { 3126 retval 3127 = cris_unknown_syscall (current_cpu, pc, 3128 "Unimplemented clone syscall " 3129 "(0x%lx, 0x%lx)\n", 3130 (unsigned long) arg1, 3131 (unsigned long) arg2); 3132 break; 3133 } 3134 3135 if (current_cpu->thread_data == NULL) 3136 make_first_thread (current_cpu); 3137 3138 /* The created thread will get the new SP and a cleared R10. 3139 Since it's created out of a copy of the old thread and we 3140 don't have a set-register-function that just take the 3141 cpu_data as a parameter, we set the childs values first, 3142 and write back or overwrite them in the parent after the 3143 copy. */ 3144 (*CPU_REG_FETCH (current_cpu)) (current_cpu, 3145 H_GR_SP, old_sp_buf, 4); 3146 bfd_putl32 (newsp, sp_buf); 3147 (*CPU_REG_STORE (current_cpu)) (current_cpu, 3148 H_GR_SP, sp_buf, 4); 3149 (*CPU_REG_STORE (current_cpu)) (current_cpu, 3150 H_GR_R10, (bfd_byte *) zeros, 4); 3151 thread_cpu_data 3152 = (*current_cpu 3153 ->make_thread_cpu_data) (current_cpu, 3154 ¤t_cpu->cpu_data_placeholder); 3155 (*CPU_REG_STORE (current_cpu)) (current_cpu, 3156 H_GR_SP, old_sp_buf, 4); 3157 3158 retval = ++current_cpu->max_threadid + TARGET_PID; 3159 3160 /* Find an unused slot. After a few threads have been created 3161 and exited, the array is expected to be a bit fragmented. 3162 We don't reuse the first entry, though, that of the 3163 original thread. */ 3164 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++) 3165 if (current_cpu->thread_data[i].cpu_context == NULL 3166 /* Don't reuse a zombied entry. */ 3167 && current_cpu->thread_data[i].threadid == 0) 3168 break; 3169 3170 memcpy (¤t_cpu->thread_data[i], 3171 ¤t_cpu->thread_data[threadno], 3172 sizeof (current_cpu->thread_data[i])); 3173 current_cpu->thread_data[i].cpu_context = thread_cpu_data; 3174 current_cpu->thread_data[i].cpu_context_atsignal = NULL; 3175 current_cpu->thread_data[i].threadid = current_cpu->max_threadid; 3176 current_cpu->thread_data[i].parent_threadid 3177 = current_cpu->thread_data[threadno].threadid; 3178 current_cpu->thread_data[i].pipe_read_fd = 0; 3179 current_cpu->thread_data[i].pipe_write_fd = 0; 3180 current_cpu->thread_data[i].at_syscall = 0; 3181 current_cpu->thread_data[i].sigpending = 0; 3182 current_cpu->thread_data[i].sigsuspended = 0; 3183 current_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL; 3184 current_cpu->m1threads = nthreads; 3185 break; 3186 } 3187 3188 /* Better watch these in case they do something necessary. */ 3189 case TARGET_SYS_socketcall: 3190 retval = -cb_host_to_target_errno (cb, ENOSYS); 3191 break; 3192 3193 case TARGET_SYS_set_thread_area: 3194 /* Do the same error check as Linux. */ 3195 if (arg1 & 255) 3196 { 3197 retval = -cb_host_to_target_errno (cb, EINVAL); 3198 break; 3199 } 3200 (*current_cpu->set_target_thread_data) (current_cpu, arg1); 3201 retval = 0; 3202 break; 3203 3204 unimplemented_syscall: 3205 default: 3206 retval 3207 = cris_unknown_syscall (current_cpu, pc, 3208 "Unimplemented syscall: %d " 3209 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", 3210 callnum, arg1, arg2, arg3, arg4, arg5, 3211 arg6); 3212 } 3213 } 3214 3215 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */ 3216 if (callnum == TARGET_SYS_open) 3217 { 3218 current_cpu->last_open_fd = retval; 3219 current_cpu->last_open_flags = arg2; 3220 } 3221 3222 current_cpu->last_syscall = callnum; 3223 3224 /* A system call is a rescheduling point. For the time being, we don't 3225 reschedule anywhere else. */ 3226 if (current_cpu->m1threads != 0 3227 /* We need to schedule off from an exiting thread that is the 3228 second-last one. */ 3229 || (current_cpu->thread_data != NULL 3230 && current_cpu->thread_data[threadno].cpu_context == NULL)) 3231 { 3232 bfd_byte retval_buf[4]; 3233 3234 current_cpu->thread_data[threadno].last_execution 3235 = TARGET_TIME_MS (current_cpu); 3236 bfd_putl32 (retval, retval_buf); 3237 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4); 3238 3239 current_cpu->thread_data[threadno].at_syscall = 1; 3240 reschedule (current_cpu); 3241 3242 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4); 3243 retval = bfd_getl32 (retval_buf); 3244 } 3245 3246 return retval; 3247} 3248 3249/* Callback from simulator write saying that the pipe at (reader, writer) 3250 is now non-empty (so the writer should wait until the pipe is empty, at 3251 least not write to this or any other pipe). Simplest is to just wait 3252 until the pipe is empty. */ 3253 3254static void 3255cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED, 3256 int reader, int writer) 3257{ 3258 SIM_CPU *cpu = current_cpu_for_cb_callback; 3259 const bfd_byte zeros[4] = { 0, 0, 0, 0 }; 3260 3261 /* It's the current thread: we just have to re-run the current 3262 syscall instruction (presumably "break 13") and change the syscall 3263 to the special simulator-wait code. Oh, and set a marker that 3264 we're waiting, so we can disambiguate the special call from a 3265 program error. 3266 3267 This function may be called multiple times between cris_pipe_empty, 3268 but we must avoid e.g. decreasing PC every time. Check fd markers 3269 to tell. */ 3270 if (cpu->thread_data == NULL) 3271 { 3272 sim_io_eprintf (CPU_STATE (cpu), 3273 "Terminating simulation due to writing pipe rd:wr %d:%d" 3274 " from one single thread\n", reader, writer); 3275 sim_engine_halt (CPU_STATE (cpu), cpu, 3276 NULL, sim_pc_get (cpu), sim_stopped, SIM_SIGILL); 3277 } 3278 else if (cpu->thread_data[cpu->threadno].pipe_write_fd == 0) 3279 { 3280 cpu->thread_data[cpu->threadno].pipe_write_fd = writer; 3281 cpu->thread_data[cpu->threadno].pipe_read_fd = reader; 3282 /* FIXME: We really shouldn't change registers other than R10 in 3283 syscalls (like R9), here or elsewhere. */ 3284 (*CPU_REG_STORE (cpu)) (cpu, H_GR_R9, (bfd_byte *) zeros, 4); 3285 sim_pc_set (cpu, sim_pc_get (cpu) - 2); 3286 } 3287} 3288 3289/* Callback from simulator close or read call saying that the pipe at 3290 (reader, writer) is now empty (so the writer can write again, perhaps 3291 leave a waiting state). If there are bytes remaining, they couldn't be 3292 consumed (perhaps due to the pipe closing). */ 3293 3294static void 3295cris_pipe_empty (host_callback *cb, 3296 int reader, 3297 int writer) 3298{ 3299 int i; 3300 SIM_CPU *cpu = current_cpu_for_cb_callback; 3301 SIM_DESC sd = CPU_STATE (current_cpu_for_cb_callback); 3302 bfd_byte r10_buf[4]; 3303 int remaining 3304 = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size; 3305 3306 /* We need to find the thread that waits for this pipe. */ 3307 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++) 3308 if (cpu->thread_data[i].cpu_context 3309 && cpu->thread_data[i].pipe_write_fd == writer) 3310 { 3311 int retval; 3312 3313 /* Temporarily switch to this cpu context, so we can change the 3314 PC by ordinary calls. */ 3315 3316 memcpy (cpu->thread_data[cpu->threadno].cpu_context, 3317 &cpu->cpu_data_placeholder, 3318 cpu->thread_cpu_data_size); 3319 memcpy (&cpu->cpu_data_placeholder, 3320 cpu->thread_data[i].cpu_context, 3321 cpu->thread_cpu_data_size); 3322 3323 /* The return value is supposed to contain the number of 3324 written bytes, which is the number of bytes requested and 3325 returned at the write call. You might think the right 3326 thing is to adjust the return-value to be only the 3327 *consumed* number of bytes, but it isn't. We're only 3328 called if the pipe buffer is fully consumed or it is being 3329 closed, possibly with remaining bytes. For the latter 3330 case, the writer is still supposed to see success for 3331 PIPE_BUF bytes (a constant which we happen to know and is 3332 unlikely to change). The return value may also be a 3333 negative number; an error value. This case is covered 3334 because "remaining" is always >= 0. */ 3335 (*CPU_REG_FETCH (cpu)) (cpu, H_GR_R10, r10_buf, 4); 3336 retval = (int) bfd_getl_signed_32 (r10_buf); 3337 if (retval - remaining > TARGET_PIPE_BUF) 3338 { 3339 bfd_putl32 (retval - remaining, r10_buf); 3340 (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4); 3341 } 3342 sim_pc_set (cpu, sim_pc_get (cpu) + 2); 3343 memcpy (cpu->thread_data[i].cpu_context, 3344 &cpu->cpu_data_placeholder, 3345 cpu->thread_cpu_data_size); 3346 memcpy (&cpu->cpu_data_placeholder, 3347 cpu->thread_data[cpu->threadno].cpu_context, 3348 cpu->thread_cpu_data_size); 3349 cpu->thread_data[i].pipe_read_fd = 0; 3350 cpu->thread_data[i].pipe_write_fd = 0; 3351 return; 3352 } 3353 3354 abort (); 3355} 3356 3357/* We have a simulator-specific notion of time. See TARGET_TIME. */ 3358 3359static long 3360cris_time (host_callback *cb ATTRIBUTE_UNUSED, long *t) 3361{ 3362 long retval = TARGET_TIME (current_cpu_for_cb_callback); 3363 if (t) 3364 *t = retval; 3365 return retval; 3366} 3367 3368/* Set target-specific callback data. */ 3369 3370void 3371cris_set_callbacks (host_callback *cb) 3372{ 3373 /* Yeargh, have to cast away constness to avoid warnings. */ 3374 cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_map; 3375 cb->errno_map = (CB_TARGET_DEFS_MAP *) errno_map; 3376 3377 /* The kernel stat64 layout. If we see a file > 2G, the "long" 3378 parameter to cb_store_target_endian will make st_size negative. 3379 Similarly for st_ino. FIXME: Find a 64-bit type, and use it 3380 *unsigned*, and/or add syntax for signed-ness. */ 3381 cb->stat_map = stat_map; 3382 cb->open_map = (CB_TARGET_DEFS_MAP *) open_map; 3383 cb->pipe_nonempty = cris_pipe_nonempty; 3384 cb->pipe_empty = cris_pipe_empty; 3385 cb->time = cris_time; 3386} 3387 3388/* Process an address exception. */ 3389 3390void 3391cris_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia, 3392 unsigned int map, int nr_bytes, address_word addr, 3393 transfer_type transfer, sim_core_signals sig) 3394{ 3395 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr, 3396 transfer, sig); 3397} 3398