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