1 /* m32r exception, interrupt, and trap (EIT) support 2 Copyright (C) 1998-2024 Free Software Foundation, Inc. 3 Contributed by Cygnus Solutions & Renesas. 4 5 This file is part of GDB, the GNU debugger. 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 /* This must come before any other includes. */ 21 #include "defs.h" 22 23 #include "portability.h" 24 #include "sim-main.h" 25 #include "sim-signal.h" 26 #include "sim-syscall.h" 27 #include "sim/callback.h" 28 #include "syscall.h" 29 #include <dirent.h> 30 #include <errno.h> 31 #include <fcntl.h> 32 #include <stdlib.h> 33 #include <time.h> 34 #include <unistd.h> 35 #include <utime.h> 36 /* TODO: The Linux syscall emulation needs work to support non-Linux hosts. 37 Use an OS hack for now so the CPU emulation is available everywhere. 38 NB: The emulation is also missing argument conversion (endian & bitsize) 39 even on Linux hosts. */ 40 #ifdef __linux__ 41 #include <syslog.h> 42 #include <sys/file.h> 43 #include <sys/fsuid.h> 44 #include <sys/ioctl.h> 45 #include <sys/mman.h> 46 #include <sys/poll.h> 47 #include <sys/resource.h> 48 #include <sys/sendfile.h> 49 #include <sys/sysinfo.h> 50 #include <sys/stat.h> 51 #include <sys/time.h> 52 #include <sys/timeb.h> 53 #include <sys/timex.h> 54 #include <sys/types.h> 55 #include <sys/uio.h> 56 #include <sys/utsname.h> 57 #include <sys/vfs.h> 58 #include <linux/sysctl.h> 59 #include <linux/types.h> 60 #include <linux/unistd.h> 61 #endif 62 63 #include "m32r-sim.h" 64 65 #define TRAP_LINUX_SYSCALL 2 66 #define TRAP_FLUSH_CACHE 12 67 /* The semantic code invokes this for invalid (unrecognized) instructions. */ 68 69 SEM_PC 70 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC pc) 71 { 72 SIM_DESC sd = CPU_STATE (current_cpu); 73 74 #if 0 75 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) 76 { 77 h_bsm_set (current_cpu, h_sm_get (current_cpu)); 78 h_bie_set (current_cpu, h_ie_get (current_cpu)); 79 h_bcond_set (current_cpu, h_cond_get (current_cpu)); 80 /* sm not changed */ 81 h_ie_set (current_cpu, 0); 82 h_cond_set (current_cpu, 0); 83 84 h_bpc_set (current_cpu, cia); 85 86 sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL, 87 EIT_RSVD_INSN_ADDR); 88 } 89 else 90 #endif 91 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL); 92 93 return pc; 94 } 95 96 /* Process an address exception. */ 97 98 void 99 m32r_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia, 100 unsigned int map, int nr_bytes, address_word addr, 101 transfer_type transfer, sim_core_signals sig) 102 { 103 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) 104 { 105 m32rbf_h_cr_set (current_cpu, H_CR_BBPC, 106 m32rbf_h_cr_get (current_cpu, H_CR_BPC)); 107 switch (MACH_NUM (CPU_MACH (current_cpu))) 108 { 109 case MACH_M32R: 110 m32rbf_h_bpsw_set (current_cpu, m32rbf_h_psw_get (current_cpu)); 111 /* sm not changed. */ 112 m32rbf_h_psw_set (current_cpu, m32rbf_h_psw_get (current_cpu) & 0x80); 113 break; 114 case MACH_M32RX: 115 m32rxf_h_bpsw_set (current_cpu, m32rxf_h_psw_get (current_cpu)); 116 /* sm not changed. */ 117 m32rxf_h_psw_set (current_cpu, m32rxf_h_psw_get (current_cpu) & 0x80); 118 break; 119 case MACH_M32R2: 120 m32r2f_h_bpsw_set (current_cpu, m32r2f_h_psw_get (current_cpu)); 121 /* sm not changed. */ 122 m32r2f_h_psw_set (current_cpu, m32r2f_h_psw_get (current_cpu) & 0x80); 123 break; 124 default: 125 abort (); 126 } 127 128 m32rbf_h_cr_set (current_cpu, H_CR_BPC, cia); 129 130 sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL, 131 EIT_ADDR_EXCP_ADDR); 132 } 133 else 134 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr, 135 transfer, sig); 136 } 137 138 /* Translate target's address to host's address. */ 139 140 static void * 141 t2h_addr (host_callback *cb, struct cb_syscall *sc, 142 unsigned long taddr) 143 { 144 SIM_DESC sd = (SIM_DESC) sc->p1; 145 SIM_CPU *cpu = (SIM_CPU *) sc->p2; 146 147 if (taddr == 0) 148 return NULL; 149 150 return sim_core_trans_addr (sd, cpu, read_map, taddr); 151 } 152 153 /* TODO: These functions are a big hack and assume that the host runtime has 154 type sizes and struct layouts that match the target. So the Linux emulation 155 probaly only really works in 32-bit runtimes. */ 156 157 static void 158 translate_endian_h2t (void *addr, size_t size) 159 { 160 unsigned int *p = (unsigned int *) addr; 161 int i; 162 163 for (i = 0; i <= size - 4; i += 4,p++) 164 *p = H2T_4 (*p); 165 166 if (i <= size - 2) 167 *((unsigned short *) p) = H2T_2 (*((unsigned short *) p)); 168 } 169 170 static void 171 translate_endian_t2h (void *addr, size_t size) 172 { 173 unsigned int *p = (unsigned int *) addr; 174 int i; 175 176 for (i = 0; i <= size - 4; i += 4,p++) 177 *p = T2H_4 (*p); 178 179 if (i <= size - 2) 180 *((unsigned short *) p) = T2H_2 (*((unsigned short *) p)); 181 } 182 183 /* Trap support. 184 The result is the pc address to continue at. 185 Preprocessing like saving the various registers has already been done. */ 186 187 USI 188 m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num) 189 { 190 SIM_DESC sd = CPU_STATE (current_cpu); 191 host_callback *cb = STATE_CALLBACK (sd); 192 193 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) 194 goto case_default; 195 196 switch (num) 197 { 198 case TRAP_SYSCALL: 199 { 200 long result, result2; 201 int errcode; 202 203 sim_syscall_multi (current_cpu, 204 m32rbf_h_gr_get (current_cpu, 0), 205 m32rbf_h_gr_get (current_cpu, 1), 206 m32rbf_h_gr_get (current_cpu, 2), 207 m32rbf_h_gr_get (current_cpu, 3), 208 m32rbf_h_gr_get (current_cpu, 4), 209 &result, &result2, &errcode); 210 211 m32rbf_h_gr_set (current_cpu, 2, errcode); 212 m32rbf_h_gr_set (current_cpu, 0, result); 213 m32rbf_h_gr_set (current_cpu, 1, result2); 214 break; 215 } 216 217 #ifdef __linux__ 218 case TRAP_LINUX_SYSCALL: 219 { 220 CB_SYSCALL s; 221 unsigned int func, arg1, arg2, arg3, arg4, arg5, arg6, arg7; 222 int result, errcode; 223 224 if (STATE_ENVIRONMENT (sd) != USER_ENVIRONMENT) 225 goto case_default; 226 227 func = m32rbf_h_gr_get (current_cpu, 7); 228 arg1 = m32rbf_h_gr_get (current_cpu, 0); 229 arg2 = m32rbf_h_gr_get (current_cpu, 1); 230 arg3 = m32rbf_h_gr_get (current_cpu, 2); 231 arg4 = m32rbf_h_gr_get (current_cpu, 3); 232 arg5 = m32rbf_h_gr_get (current_cpu, 4); 233 arg6 = m32rbf_h_gr_get (current_cpu, 5); 234 arg7 = m32rbf_h_gr_get (current_cpu, 6); 235 236 CB_SYSCALL_INIT (&s); 237 s.func = func; 238 s.arg1 = arg1; 239 s.arg2 = arg2; 240 s.arg3 = arg3; 241 s.arg4 = arg4; 242 s.arg5 = arg5; 243 s.arg6 = arg6; 244 s.arg7 = arg7; 245 246 s.p1 = sd; 247 s.p2 = current_cpu; 248 s.read_mem = sim_syscall_read_mem; 249 s.write_mem = sim_syscall_write_mem; 250 251 result = 0; 252 errcode = 0; 253 254 switch (func) 255 { 256 case TARGET_LINUX_SYS_exit: 257 sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1); 258 break; 259 260 case TARGET_LINUX_SYS_read: 261 result = read (arg1, t2h_addr (cb, &s, arg2), arg3); 262 errcode = errno; 263 break; 264 265 case TARGET_LINUX_SYS_write: 266 result = write (arg1, t2h_addr (cb, &s, arg2), arg3); 267 errcode = errno; 268 break; 269 270 case TARGET_LINUX_SYS_open: 271 result = open ((char *) t2h_addr (cb, &s, arg1), arg2, arg3); 272 errcode = errno; 273 break; 274 275 case TARGET_LINUX_SYS_close: 276 result = close (arg1); 277 errcode = errno; 278 break; 279 280 case TARGET_LINUX_SYS_creat: 281 result = creat ((char *) t2h_addr (cb, &s, arg1), arg2); 282 errcode = errno; 283 break; 284 285 case TARGET_LINUX_SYS_link: 286 result = link ((char *) t2h_addr (cb, &s, arg1), 287 (char *) t2h_addr (cb, &s, arg2)); 288 errcode = errno; 289 break; 290 291 case TARGET_LINUX_SYS_unlink: 292 result = unlink ((char *) t2h_addr (cb, &s, arg1)); 293 errcode = errno; 294 break; 295 296 case TARGET_LINUX_SYS_chdir: 297 result = chdir ((char *) t2h_addr (cb, &s, arg1)); 298 errcode = errno; 299 break; 300 301 case TARGET_LINUX_SYS_time: 302 { 303 time_t t; 304 305 if (arg1 == 0) 306 { 307 result = (int) time (NULL); 308 errcode = errno; 309 } 310 else 311 { 312 result = (int) time (&t); 313 errcode = errno; 314 315 if (result != 0) 316 break; 317 318 t = H2T_4 (t); 319 if ((s.write_mem) (cb, &s, arg1, (char *) &t, sizeof(t)) != sizeof(t)) 320 { 321 result = -1; 322 errcode = EINVAL; 323 } 324 } 325 } 326 break; 327 328 case TARGET_LINUX_SYS_mknod: 329 result = mknod ((char *) t2h_addr (cb, &s, arg1), 330 (mode_t) arg2, (dev_t) arg3); 331 errcode = errno; 332 break; 333 334 case TARGET_LINUX_SYS_chmod: 335 result = chmod ((char *) t2h_addr (cb, &s, arg1), (mode_t) arg2); 336 errcode = errno; 337 break; 338 339 case TARGET_LINUX_SYS_lchown32: 340 case TARGET_LINUX_SYS_lchown: 341 result = lchown ((char *) t2h_addr (cb, &s, arg1), 342 (uid_t) arg2, (gid_t) arg3); 343 errcode = errno; 344 break; 345 346 case TARGET_LINUX_SYS_lseek: 347 result = (int) lseek (arg1, (off_t) arg2, arg3); 348 errcode = errno; 349 break; 350 351 case TARGET_LINUX_SYS_getpid: 352 result = getpid (); 353 errcode = errno; 354 break; 355 356 case TARGET_LINUX_SYS_getuid32: 357 case TARGET_LINUX_SYS_getuid: 358 result = getuid (); 359 errcode = errno; 360 break; 361 362 case TARGET_LINUX_SYS_utime: 363 { 364 struct utimbuf buf; 365 366 if (arg2 == 0) 367 { 368 result = utime ((char *) t2h_addr (cb, &s, arg1), NULL); 369 errcode = errno; 370 } 371 else 372 { 373 buf = *((struct utimbuf *) t2h_addr (cb, &s, arg2)); 374 translate_endian_t2h (&buf, sizeof(buf)); 375 result = utime ((char *) t2h_addr (cb, &s, arg1), &buf); 376 errcode = errno; 377 } 378 } 379 break; 380 381 case TARGET_LINUX_SYS_access: 382 result = access ((char *) t2h_addr (cb, &s, arg1), arg2); 383 errcode = errno; 384 break; 385 386 case TARGET_LINUX_SYS_ftime: 387 { 388 struct timeb t; 389 struct timespec ts; 390 391 result = clock_gettime (CLOCK_REALTIME, &ts); 392 errcode = errno; 393 394 if (result != 0) 395 break; 396 397 t.time = H2T_4 (ts.tv_sec); 398 t.millitm = H2T_2 (ts.tv_nsec / 1000000); 399 /* POSIX.1-2001 says the contents of the timezone and dstflag 400 members of tp after a call to ftime() are unspecified. */ 401 t.timezone = H2T_2 (0); 402 t.dstflag = H2T_2 (0); 403 if ((s.write_mem) (cb, &s, arg1, (char *) &t, sizeof(t)) 404 != sizeof(t)) 405 { 406 result = -1; 407 errcode = EINVAL; 408 } 409 } 410 break; 411 412 case TARGET_LINUX_SYS_sync: 413 sync (); 414 result = 0; 415 break; 416 417 case TARGET_LINUX_SYS_rename: 418 result = rename ((char *) t2h_addr (cb, &s, arg1), 419 (char *) t2h_addr (cb, &s, arg2)); 420 errcode = errno; 421 break; 422 423 case TARGET_LINUX_SYS_mkdir: 424 result = mkdir ((char *) t2h_addr (cb, &s, arg1), arg2); 425 errcode = errno; 426 break; 427 428 case TARGET_LINUX_SYS_rmdir: 429 result = rmdir ((char *) t2h_addr (cb, &s, arg1)); 430 errcode = errno; 431 break; 432 433 case TARGET_LINUX_SYS_dup: 434 result = dup (arg1); 435 errcode = errno; 436 break; 437 438 case TARGET_LINUX_SYS_brk: 439 result = brk ((void *) (uintptr_t) arg1); 440 errcode = errno; 441 //result = arg1; 442 break; 443 444 case TARGET_LINUX_SYS_getgid32: 445 case TARGET_LINUX_SYS_getgid: 446 result = getgid (); 447 errcode = errno; 448 break; 449 450 case TARGET_LINUX_SYS_geteuid32: 451 case TARGET_LINUX_SYS_geteuid: 452 result = geteuid (); 453 errcode = errno; 454 break; 455 456 case TARGET_LINUX_SYS_getegid32: 457 case TARGET_LINUX_SYS_getegid: 458 result = getegid (); 459 errcode = errno; 460 break; 461 462 case TARGET_LINUX_SYS_ioctl: 463 result = ioctl (arg1, arg2, arg3); 464 errcode = errno; 465 break; 466 467 case TARGET_LINUX_SYS_fcntl: 468 result = fcntl (arg1, arg2, arg3); 469 errcode = errno; 470 break; 471 472 case TARGET_LINUX_SYS_dup2: 473 result = dup2 (arg1, arg2); 474 errcode = errno; 475 break; 476 477 case TARGET_LINUX_SYS_getppid: 478 result = getppid (); 479 errcode = errno; 480 break; 481 482 case TARGET_LINUX_SYS_getpgrp: 483 result = getpgrp (); 484 errcode = errno; 485 break; 486 487 case TARGET_LINUX_SYS_getrlimit: 488 { 489 struct rlimit rlim; 490 491 result = getrlimit (arg1, &rlim); 492 errcode = errno; 493 494 if (result != 0) 495 break; 496 497 translate_endian_h2t (&rlim, sizeof(rlim)); 498 if ((s.write_mem) (cb, &s, arg2, (char *) &rlim, sizeof(rlim)) 499 != sizeof(rlim)) 500 { 501 result = -1; 502 errcode = EINVAL; 503 } 504 } 505 break; 506 507 case TARGET_LINUX_SYS_getrusage: 508 { 509 struct rusage usage; 510 511 result = getrusage (arg1, &usage); 512 errcode = errno; 513 514 if (result != 0) 515 break; 516 517 translate_endian_h2t (&usage, sizeof(usage)); 518 if ((s.write_mem) (cb, &s, arg2, (char *) &usage, sizeof(usage)) 519 != sizeof(usage)) 520 { 521 result = -1; 522 errcode = EINVAL; 523 } 524 } 525 break; 526 527 case TARGET_LINUX_SYS_gettimeofday: 528 { 529 struct timeval tv; 530 struct timezone tz; 531 532 result = gettimeofday (&tv, &tz); 533 errcode = errno; 534 535 if (result != 0) 536 break; 537 538 translate_endian_h2t (&tv, sizeof(tv)); 539 if ((s.write_mem) (cb, &s, arg1, (char *) &tv, sizeof(tv)) 540 != sizeof(tv)) 541 { 542 result = -1; 543 errcode = EINVAL; 544 } 545 546 translate_endian_h2t (&tz, sizeof(tz)); 547 if ((s.write_mem) (cb, &s, arg2, (char *) &tz, sizeof(tz)) 548 != sizeof(tz)) 549 { 550 result = -1; 551 errcode = EINVAL; 552 } 553 } 554 break; 555 556 case TARGET_LINUX_SYS_getgroups32: 557 case TARGET_LINUX_SYS_getgroups: 558 { 559 gid_t *list = NULL; 560 561 if (arg1 > 0) 562 list = (gid_t *) malloc (arg1 * sizeof(gid_t)); 563 564 result = getgroups (arg1, list); 565 errcode = errno; 566 567 if (result != 0) 568 break; 569 570 translate_endian_h2t (list, arg1 * sizeof(gid_t)); 571 if (arg1 > 0) 572 if ((s.write_mem) (cb, &s, arg2, (char *) list, arg1 * sizeof(gid_t)) 573 != arg1 * sizeof(gid_t)) 574 { 575 result = -1; 576 errcode = EINVAL; 577 } 578 } 579 break; 580 581 case TARGET_LINUX_SYS_select: 582 { 583 int n; 584 fd_set readfds; 585 unsigned int treadfdsp; 586 fd_set *hreadfdsp; 587 fd_set writefds; 588 unsigned int twritefdsp; 589 fd_set *hwritefdsp; 590 fd_set exceptfds; 591 unsigned int texceptfdsp; 592 fd_set *hexceptfdsp; 593 unsigned int ttimeoutp; 594 struct timeval timeout; 595 596 n = arg1; 597 598 treadfdsp = arg2; 599 if (treadfdsp !=0) 600 { 601 readfds = *((fd_set *) t2h_addr (cb, &s, treadfdsp)); 602 translate_endian_t2h (&readfds, sizeof(readfds)); 603 hreadfdsp = &readfds; 604 } 605 else 606 hreadfdsp = NULL; 607 608 twritefdsp = arg3; 609 if (twritefdsp != 0) 610 { 611 writefds = *((fd_set *) t2h_addr (cb, &s, twritefdsp)); 612 translate_endian_t2h (&writefds, sizeof(writefds)); 613 hwritefdsp = &writefds; 614 } 615 else 616 hwritefdsp = NULL; 617 618 texceptfdsp = arg4; 619 if (texceptfdsp != 0) 620 { 621 exceptfds = *((fd_set *) t2h_addr (cb, &s, texceptfdsp)); 622 translate_endian_t2h (&exceptfds, sizeof(exceptfds)); 623 hexceptfdsp = &exceptfds; 624 } 625 else 626 hexceptfdsp = NULL; 627 628 ttimeoutp = arg5; 629 timeout = *((struct timeval *) t2h_addr (cb, &s, ttimeoutp)); 630 translate_endian_t2h (&timeout, sizeof(timeout)); 631 632 result = select (n, hreadfdsp, hwritefdsp, hexceptfdsp, &timeout); 633 errcode = errno; 634 635 if (result != 0) 636 break; 637 638 if (treadfdsp != 0) 639 { 640 translate_endian_h2t (&readfds, sizeof(readfds)); 641 if ((s.write_mem) (cb, &s, treadfdsp, 642 (char *) &readfds, sizeof(readfds)) != sizeof(readfds)) 643 { 644 result = -1; 645 errcode = EINVAL; 646 } 647 } 648 649 if (twritefdsp != 0) 650 { 651 translate_endian_h2t (&writefds, sizeof(writefds)); 652 if ((s.write_mem) (cb, &s, twritefdsp, 653 (char *) &writefds, sizeof(writefds)) != sizeof(writefds)) 654 { 655 result = -1; 656 errcode = EINVAL; 657 } 658 } 659 660 if (texceptfdsp != 0) 661 { 662 translate_endian_h2t (&exceptfds, sizeof(exceptfds)); 663 if ((s.write_mem) (cb, &s, texceptfdsp, 664 (char *) &exceptfds, sizeof(exceptfds)) != sizeof(exceptfds)) 665 { 666 result = -1; 667 errcode = EINVAL; 668 } 669 } 670 671 translate_endian_h2t (&timeout, sizeof(timeout)); 672 if ((s.write_mem) (cb, &s, ttimeoutp, 673 (char *) &timeout, sizeof(timeout)) != sizeof(timeout)) 674 { 675 result = -1; 676 errcode = EINVAL; 677 } 678 } 679 break; 680 681 case TARGET_LINUX_SYS_symlink: 682 result = symlink ((char *) t2h_addr (cb, &s, arg1), 683 (char *) t2h_addr (cb, &s, arg2)); 684 errcode = errno; 685 break; 686 687 case TARGET_LINUX_SYS_readlink: 688 result = readlink ((char *) t2h_addr (cb, &s, arg1), 689 (char *) t2h_addr (cb, &s, arg2), 690 arg3); 691 errcode = errno; 692 break; 693 694 case TARGET_LINUX_SYS_readdir: 695 #if SIZEOF_VOID_P == 4 696 result = (int) readdir ((DIR *) t2h_addr (cb, &s, arg1)); 697 errcode = errno; 698 #else 699 result = 0; 700 errcode = ENOSYS; 701 #endif 702 break; 703 704 #if 0 705 case TARGET_LINUX_SYS_mmap: 706 { 707 result = (int) mmap ((void *) t2h_addr (cb, &s, arg1), 708 arg2, arg3, arg4, arg5, arg6); 709 errcode = errno; 710 711 if (errno == 0) 712 { 713 sim_core_attach (sd, NULL, 714 0, access_read_write_exec, 0, 715 result, arg2, 0, NULL, NULL); 716 } 717 } 718 break; 719 #endif 720 case TARGET_LINUX_SYS_mmap2: 721 { 722 #if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */ 723 void *addr; 724 size_t len; 725 int prot, flags, fildes; 726 off_t off; 727 728 addr = (void *) t2h_addr (cb, &s, arg1); 729 len = arg2; 730 prot = arg3; 731 flags = arg4; 732 fildes = arg5; 733 off = arg6 << 12; 734 735 result = (int) mmap (addr, len, prot, flags, fildes, off); 736 errcode = errno; 737 if (result != -1) 738 { 739 char c; 740 if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0) 741 sim_core_attach (sd, NULL, 742 0, access_read_write_exec, 0, 743 result, len, 0, NULL, NULL); 744 } 745 #else 746 result = 0; 747 errcode = ENOSYS; 748 #endif 749 } 750 break; 751 752 case TARGET_LINUX_SYS_mmap: 753 { 754 #if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */ 755 void *addr; 756 size_t len; 757 int prot, flags, fildes; 758 off_t off; 759 760 addr = *((void **) t2h_addr (cb, &s, arg1)); 761 len = *((size_t *) t2h_addr (cb, &s, arg1 + 4)); 762 prot = *((int *) t2h_addr (cb, &s, arg1 + 8)); 763 flags = *((int *) t2h_addr (cb, &s, arg1 + 12)); 764 fildes = *((int *) t2h_addr (cb, &s, arg1 + 16)); 765 off = *((off_t *) t2h_addr (cb, &s, arg1 + 20)); 766 767 addr = (void *) T2H_4 ((unsigned int) addr); 768 len = T2H_4 (len); 769 prot = T2H_4 (prot); 770 flags = T2H_4 (flags); 771 fildes = T2H_4 (fildes); 772 off = T2H_4 (off); 773 774 //addr = (void *) t2h_addr (cb, &s, (unsigned int) addr); 775 result = (int) mmap (addr, len, prot, flags, fildes, off); 776 errcode = errno; 777 778 //if (errno == 0) 779 if (result != -1) 780 { 781 char c; 782 if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0) 783 sim_core_attach (sd, NULL, 784 0, access_read_write_exec, 0, 785 result, len, 0, NULL, NULL); 786 } 787 #else 788 result = 0; 789 errcode = ENOSYS; 790 #endif 791 } 792 break; 793 794 case TARGET_LINUX_SYS_munmap: 795 result = munmap ((void *) (uintptr_t) arg1, arg2); 796 errcode = errno; 797 if (result != -1) 798 sim_core_detach (sd, NULL, 0, arg2, result); 799 break; 800 801 case TARGET_LINUX_SYS_truncate: 802 result = truncate ((char *) t2h_addr (cb, &s, arg1), arg2); 803 errcode = errno; 804 break; 805 806 case TARGET_LINUX_SYS_ftruncate: 807 result = ftruncate (arg1, arg2); 808 errcode = errno; 809 break; 810 811 case TARGET_LINUX_SYS_fchmod: 812 result = fchmod (arg1, arg2); 813 errcode = errno; 814 break; 815 816 case TARGET_LINUX_SYS_fchown32: 817 case TARGET_LINUX_SYS_fchown: 818 result = fchown (arg1, arg2, arg3); 819 errcode = errno; 820 break; 821 822 case TARGET_LINUX_SYS_statfs: 823 { 824 struct statfs statbuf; 825 826 result = statfs ((char *) t2h_addr (cb, &s, arg1), &statbuf); 827 errcode = errno; 828 829 if (result != 0) 830 break; 831 832 translate_endian_h2t (&statbuf, sizeof(statbuf)); 833 if ((s.write_mem) (cb, &s, arg2, (char *) &statbuf, sizeof(statbuf)) 834 != sizeof(statbuf)) 835 { 836 result = -1; 837 errcode = EINVAL; 838 } 839 } 840 break; 841 842 case TARGET_LINUX_SYS_fstatfs: 843 { 844 struct statfs statbuf; 845 846 result = fstatfs (arg1, &statbuf); 847 errcode = errno; 848 849 if (result != 0) 850 break; 851 852 translate_endian_h2t (&statbuf, sizeof(statbuf)); 853 if ((s.write_mem) (cb, &s, arg2, (char *) &statbuf, sizeof(statbuf)) 854 != sizeof(statbuf)) 855 { 856 result = -1; 857 errcode = EINVAL; 858 } 859 } 860 break; 861 862 case TARGET_LINUX_SYS_syslog: 863 syslog (arg1, "%s", (char *) t2h_addr (cb, &s, arg2)); 864 result = 0; 865 errcode = errno; 866 break; 867 868 case TARGET_LINUX_SYS_setitimer: 869 { 870 struct itimerval value, ovalue; 871 872 value = *((struct itimerval *) t2h_addr (cb, &s, arg2)); 873 translate_endian_t2h (&value, sizeof(value)); 874 875 if (arg2 == 0) 876 { 877 result = setitimer (arg1, &value, NULL); 878 errcode = errno; 879 } 880 else 881 { 882 result = setitimer (arg1, &value, &ovalue); 883 errcode = errno; 884 885 if (result != 0) 886 break; 887 888 translate_endian_h2t (&ovalue, sizeof(ovalue)); 889 if ((s.write_mem) (cb, &s, arg3, (char *) &ovalue, sizeof(ovalue)) 890 != sizeof(ovalue)) 891 { 892 result = -1; 893 errcode = EINVAL; 894 } 895 } 896 } 897 break; 898 899 case TARGET_LINUX_SYS_getitimer: 900 { 901 struct itimerval value; 902 903 result = getitimer (arg1, &value); 904 errcode = errno; 905 906 if (result != 0) 907 break; 908 909 translate_endian_h2t (&value, sizeof(value)); 910 if ((s.write_mem) (cb, &s, arg2, (char *) &value, sizeof(value)) 911 != sizeof(value)) 912 { 913 result = -1; 914 errcode = EINVAL; 915 } 916 } 917 break; 918 919 case TARGET_LINUX_SYS_stat: 920 { 921 char *buf; 922 int buflen; 923 struct stat statbuf; 924 925 result = stat ((char *) t2h_addr (cb, &s, arg1), &statbuf); 926 errcode = errno; 927 if (result < 0) 928 break; 929 930 buflen = cb_host_to_target_stat (cb, NULL, NULL); 931 buf = xmalloc (buflen); 932 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen) 933 { 934 /* The translation failed. This is due to an internal 935 host program error, not the target's fault. */ 936 free (buf); 937 result = -1; 938 errcode = ENOSYS; 939 break; 940 } 941 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen) 942 { 943 free (buf); 944 result = -1; 945 errcode = EINVAL; 946 break; 947 } 948 free (buf); 949 } 950 break; 951 952 case TARGET_LINUX_SYS_lstat: 953 { 954 char *buf; 955 int buflen; 956 struct stat statbuf; 957 958 result = lstat ((char *) t2h_addr (cb, &s, arg1), &statbuf); 959 errcode = errno; 960 if (result < 0) 961 break; 962 963 buflen = cb_host_to_target_stat (cb, NULL, NULL); 964 buf = xmalloc (buflen); 965 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen) 966 { 967 /* The translation failed. This is due to an internal 968 host program error, not the target's fault. */ 969 free (buf); 970 result = -1; 971 errcode = ENOSYS; 972 break; 973 } 974 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen) 975 { 976 free (buf); 977 result = -1; 978 errcode = EINVAL; 979 break; 980 } 981 free (buf); 982 } 983 break; 984 985 case TARGET_LINUX_SYS_fstat: 986 { 987 char *buf; 988 int buflen; 989 struct stat statbuf; 990 991 result = fstat (arg1, &statbuf); 992 errcode = errno; 993 if (result < 0) 994 break; 995 996 buflen = cb_host_to_target_stat (cb, NULL, NULL); 997 buf = xmalloc (buflen); 998 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen) 999 { 1000 /* The translation failed. This is due to an internal 1001 host program error, not the target's fault. */ 1002 free (buf); 1003 result = -1; 1004 errcode = ENOSYS; 1005 break; 1006 } 1007 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen) 1008 { 1009 free (buf); 1010 result = -1; 1011 errcode = EINVAL; 1012 break; 1013 } 1014 free (buf); 1015 } 1016 break; 1017 1018 case TARGET_LINUX_SYS_sysinfo: 1019 { 1020 struct sysinfo info; 1021 1022 result = sysinfo (&info); 1023 errcode = errno; 1024 1025 if (result != 0) 1026 break; 1027 1028 info.uptime = H2T_4 (info.uptime); 1029 info.loads[0] = H2T_4 (info.loads[0]); 1030 info.loads[1] = H2T_4 (info.loads[1]); 1031 info.loads[2] = H2T_4 (info.loads[2]); 1032 info.totalram = H2T_4 (info.totalram); 1033 info.freeram = H2T_4 (info.freeram); 1034 info.sharedram = H2T_4 (info.sharedram); 1035 info.bufferram = H2T_4 (info.bufferram); 1036 info.totalswap = H2T_4 (info.totalswap); 1037 info.freeswap = H2T_4 (info.freeswap); 1038 info.procs = H2T_2 (info.procs); 1039 #if LINUX_VERSION_CODE >= 0x20400 1040 info.totalhigh = H2T_4 (info.totalhigh); 1041 info.freehigh = H2T_4 (info.freehigh); 1042 info.mem_unit = H2T_4 (info.mem_unit); 1043 #endif 1044 if ((s.write_mem) (cb, &s, arg1, (char *) &info, sizeof(info)) 1045 != sizeof(info)) 1046 { 1047 result = -1; 1048 errcode = EINVAL; 1049 } 1050 } 1051 break; 1052 1053 #if 0 1054 case TARGET_LINUX_SYS_ipc: 1055 { 1056 result = ipc (arg1, arg2, arg3, arg4, 1057 (void *) t2h_addr (cb, &s, arg5), arg6); 1058 errcode = errno; 1059 } 1060 break; 1061 #endif 1062 1063 case TARGET_LINUX_SYS_fsync: 1064 result = fsync (arg1); 1065 errcode = errno; 1066 break; 1067 1068 case TARGET_LINUX_SYS_uname: 1069 /* utsname contains only arrays of char, so it is not necessary 1070 to translate endian. */ 1071 result = uname ((struct utsname *) t2h_addr (cb, &s, arg1)); 1072 errcode = errno; 1073 break; 1074 1075 case TARGET_LINUX_SYS_adjtimex: 1076 { 1077 struct timex buf; 1078 1079 result = adjtimex (&buf); 1080 errcode = errno; 1081 1082 if (result != 0) 1083 break; 1084 1085 translate_endian_h2t (&buf, sizeof(buf)); 1086 if ((s.write_mem) (cb, &s, arg1, (char *) &buf, sizeof(buf)) 1087 != sizeof(buf)) 1088 { 1089 result = -1; 1090 errcode = EINVAL; 1091 } 1092 } 1093 break; 1094 1095 case TARGET_LINUX_SYS_mprotect: 1096 result = mprotect ((void *) (uintptr_t) arg1, arg2, arg3); 1097 errcode = errno; 1098 break; 1099 1100 case TARGET_LINUX_SYS_fchdir: 1101 result = fchdir (arg1); 1102 errcode = errno; 1103 break; 1104 1105 case TARGET_LINUX_SYS_setfsuid32: 1106 case TARGET_LINUX_SYS_setfsuid: 1107 result = setfsuid (arg1); 1108 errcode = errno; 1109 break; 1110 1111 case TARGET_LINUX_SYS_setfsgid32: 1112 case TARGET_LINUX_SYS_setfsgid: 1113 result = setfsgid (arg1); 1114 errcode = errno; 1115 break; 1116 1117 #if 0 1118 case TARGET_LINUX_SYS__llseek: 1119 { 1120 loff_t buf; 1121 1122 result = _llseek (arg1, arg2, arg3, &buf, arg5); 1123 errcode = errno; 1124 1125 if (result != 0) 1126 break; 1127 1128 translate_endian_h2t (&buf, sizeof(buf)); 1129 if ((s.write_mem) (cb, &s, t2h_addr (cb, &s, arg4), 1130 (char *) &buf, sizeof(buf)) != sizeof(buf)) 1131 { 1132 result = -1; 1133 errcode = EINVAL; 1134 } 1135 } 1136 break; 1137 1138 case TARGET_LINUX_SYS_getdents: 1139 { 1140 struct dirent dir; 1141 1142 result = getdents (arg1, &dir, arg3); 1143 errcode = errno; 1144 1145 if (result != 0) 1146 break; 1147 1148 dir.d_ino = H2T_4 (dir.d_ino); 1149 dir.d_off = H2T_4 (dir.d_off); 1150 dir.d_reclen = H2T_2 (dir.d_reclen); 1151 if ((s.write_mem) (cb, &s, arg2, (char *) &dir, sizeof(dir)) 1152 != sizeof(dir)) 1153 { 1154 result = -1; 1155 errcode = EINVAL; 1156 } 1157 } 1158 break; 1159 #endif 1160 1161 case TARGET_LINUX_SYS_flock: 1162 result = flock (arg1, arg2); 1163 errcode = errno; 1164 break; 1165 1166 case TARGET_LINUX_SYS_msync: 1167 result = msync ((void *) (uintptr_t) arg1, arg2, arg3); 1168 errcode = errno; 1169 break; 1170 1171 case TARGET_LINUX_SYS_readv: 1172 { 1173 struct iovec vector; 1174 1175 vector = *((struct iovec *) t2h_addr (cb, &s, arg2)); 1176 translate_endian_t2h (&vector, sizeof(vector)); 1177 1178 result = readv (arg1, &vector, arg3); 1179 errcode = errno; 1180 } 1181 break; 1182 1183 case TARGET_LINUX_SYS_writev: 1184 { 1185 struct iovec vector; 1186 1187 vector = *((struct iovec *) t2h_addr (cb, &s, arg2)); 1188 translate_endian_t2h (&vector, sizeof(vector)); 1189 1190 result = writev (arg1, &vector, arg3); 1191 errcode = errno; 1192 } 1193 break; 1194 1195 case TARGET_LINUX_SYS_fdatasync: 1196 result = fdatasync (arg1); 1197 errcode = errno; 1198 break; 1199 1200 case TARGET_LINUX_SYS_mlock: 1201 result = mlock ((void *) t2h_addr (cb, &s, arg1), arg2); 1202 errcode = errno; 1203 break; 1204 1205 case TARGET_LINUX_SYS_munlock: 1206 result = munlock ((void *) t2h_addr (cb, &s, arg1), arg2); 1207 errcode = errno; 1208 break; 1209 1210 case TARGET_LINUX_SYS_nanosleep: 1211 { 1212 struct timespec req, rem; 1213 1214 req = *((struct timespec *) t2h_addr (cb, &s, arg2)); 1215 translate_endian_t2h (&req, sizeof(req)); 1216 1217 result = nanosleep (&req, &rem); 1218 errcode = errno; 1219 1220 if (result != 0) 1221 break; 1222 1223 translate_endian_h2t (&rem, sizeof(rem)); 1224 if ((s.write_mem) (cb, &s, arg2, (char *) &rem, sizeof(rem)) 1225 != sizeof(rem)) 1226 { 1227 result = -1; 1228 errcode = EINVAL; 1229 } 1230 } 1231 break; 1232 1233 case TARGET_LINUX_SYS_mremap: /* FIXME */ 1234 #if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */ 1235 result = (int) mremap ((void *) t2h_addr (cb, &s, arg1), arg2, arg3, arg4); 1236 errcode = errno; 1237 #else 1238 result = -1; 1239 errcode = ENOSYS; 1240 #endif 1241 break; 1242 1243 case TARGET_LINUX_SYS_getresuid32: 1244 case TARGET_LINUX_SYS_getresuid: 1245 { 1246 uid_t ruid, euid, suid; 1247 1248 result = getresuid (&ruid, &euid, &suid); 1249 errcode = errno; 1250 1251 if (result != 0) 1252 break; 1253 1254 *((uid_t *) t2h_addr (cb, &s, arg1)) = H2T_4 (ruid); 1255 *((uid_t *) t2h_addr (cb, &s, arg2)) = H2T_4 (euid); 1256 *((uid_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (suid); 1257 } 1258 break; 1259 1260 case TARGET_LINUX_SYS_poll: 1261 { 1262 struct pollfd ufds; 1263 1264 ufds = *((struct pollfd *) t2h_addr (cb, &s, arg1)); 1265 ufds.fd = T2H_4 (ufds.fd); 1266 ufds.events = T2H_2 (ufds.events); 1267 ufds.revents = T2H_2 (ufds.revents); 1268 1269 result = poll (&ufds, arg2, arg3); 1270 errcode = errno; 1271 } 1272 break; 1273 1274 case TARGET_LINUX_SYS_getresgid32: 1275 case TARGET_LINUX_SYS_getresgid: 1276 { 1277 uid_t rgid, egid, sgid; 1278 1279 result = getresgid (&rgid, &egid, &sgid); 1280 errcode = errno; 1281 1282 if (result != 0) 1283 break; 1284 1285 *((uid_t *) t2h_addr (cb, &s, arg1)) = H2T_4 (rgid); 1286 *((uid_t *) t2h_addr (cb, &s, arg2)) = H2T_4 (egid); 1287 *((uid_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (sgid); 1288 } 1289 break; 1290 1291 case TARGET_LINUX_SYS_pread: 1292 result = pread (arg1, (void *) t2h_addr (cb, &s, arg2), arg3, arg4); 1293 errcode = errno; 1294 break; 1295 1296 case TARGET_LINUX_SYS_pwrite: 1297 result = pwrite (arg1, (void *) t2h_addr (cb, &s, arg2), arg3, arg4); 1298 errcode = errno; 1299 break; 1300 1301 case TARGET_LINUX_SYS_chown32: 1302 case TARGET_LINUX_SYS_chown: 1303 result = chown ((char *) t2h_addr (cb, &s, arg1), arg2, arg3); 1304 errcode = errno; 1305 break; 1306 1307 case TARGET_LINUX_SYS_getcwd: 1308 { 1309 void *ret; 1310 1311 ret = getcwd ((char *) t2h_addr (cb, &s, arg1), arg2); 1312 result = ret == NULL ? 0 : arg1; 1313 errcode = errno; 1314 } 1315 break; 1316 1317 case TARGET_LINUX_SYS_sendfile: 1318 { 1319 off_t offset; 1320 1321 offset = *((off_t *) t2h_addr (cb, &s, arg3)); 1322 offset = T2H_4 (offset); 1323 1324 result = sendfile (arg1, arg2, &offset, arg3); 1325 errcode = errno; 1326 1327 if (result != 0) 1328 break; 1329 1330 *((off_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (offset); 1331 } 1332 break; 1333 1334 default: 1335 result = -1; 1336 errcode = ENOSYS; 1337 break; 1338 } 1339 1340 if (result == -1) 1341 m32rbf_h_gr_set (current_cpu, 0, -errcode); 1342 else 1343 m32rbf_h_gr_set (current_cpu, 0, result); 1344 break; 1345 } 1346 #endif 1347 1348 case TRAP_BREAKPOINT: 1349 sim_engine_halt (sd, current_cpu, NULL, pc, 1350 sim_stopped, SIM_SIGTRAP); 1351 break; 1352 1353 case TRAP_FLUSH_CACHE: 1354 /* Do nothing. */ 1355 break; 1356 1357 case_default: 1358 default: 1359 { 1360 /* The new pc is the trap vector entry. 1361 We assume there's a branch there to some handler. 1362 Use cr5 as EVB (EIT Vector Base) register. */ 1363 /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */ 1364 USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4; 1365 return new_pc; 1366 } 1367 } 1368 1369 /* Fake an "rte" insn. */ 1370 /* FIXME: Should duplicate all of rte processing. */ 1371 return (pc & -4) + 4; 1372 } 1373