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