]> Git Repo - binutils.git/blame - sim/m32r/traps.c
Automatic date update in version.in
[binutils.git] / sim / m32r / traps.c
CommitLineData
c906108c 1/* m32r exception, interrupt, and trap (EIT) support
4a94e368 2 Copyright (C) 1998-2022 Free Software Foundation, Inc.
fe41f721 3 Contributed by Cygnus Solutions & Renesas.
c906108c 4
16b47b25 5 This file is part of GDB, the GNU debugger.
c906108c 6
16b47b25
NC
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
4744ac1b
JB
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
c906108c 11
16b47b25
NC
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.
c906108c 16
4744ac1b
JB
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/>. */
c906108c 19
6df01ab8
MF
20/* This must come before any other includes. */
21#include "defs.h"
22
fe41f721 23#include "portability.h"
c906108c 24#include "sim-main.h"
1fef66b0 25#include "sim-signal.h"
61a0c964 26#include "sim-syscall.h"
fe41f721
MF
27#include "sim/callback.h"
28#include "syscall.h"
fe41f721
MF
29#include <dirent.h>
30#include <errno.h>
31#include <fcntl.h>
32a046ab 32#include <stdlib.h>
fe41f721
MF
33#include <time.h>
34#include <unistd.h>
35#include <utime.h>
fe7f0b01
MF
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__
fe41f721
MF
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>
fe7f0b01 56#endif
c906108c 57
fe41f721 58#define TRAP_LINUX_SYSCALL 2
16b47b25 59#define TRAP_FLUSH_CACHE 12
0b2e03b4 60/* The semantic code invokes this for invalid (unrecognized) instructions. */
c906108c 61
16b47b25
NC
62SEM_PC
63sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC pc)
c906108c
SS
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);
16b47b25
NC
85
86 return pc;
c906108c
SS
87}
88
89/* Process an address exception. */
90
91void
92m32r_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 {
16b47b25
NC
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 }
fe41f721 120
16b47b25 121 m32rbf_h_cr_set (current_cpu, H_CR_BPC, cia);
c906108c
SS
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\f
fe41f721
MF
131/* Translate target's address to host's address. */
132
133static void *
134t2h_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
151static void
152translate_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
164static void
165translate_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
c906108c
SS
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
181USI
182m32r_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
c906108c 187 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
fe41f721 188 goto case_default;
c906108c
SS
189
190 switch (num)
191 {
fe41f721 192 case TRAP_SYSCALL:
c906108c 193 {
7d5c6c43
MF
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);
c906108c
SS
208 break;
209 }
210
fe7f0b01 211#ifdef __linux__
fe41f721
MF
212 case TRAP_LINUX_SYSCALL:
213 {
214 CB_SYSCALL s;
54af6227
MF
215 unsigned int func, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
216 int result, result2, errcode;
fe41f721
MF
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
54af6227
MF
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
845cbaa9
AM
240 s.p1 = sd;
241 s.p2 = current_cpu;
54af6227
MF
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:
fe41f721 252 sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
54af6227
MF
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 {
45f8296e 550 gid_t *list = NULL;
54af6227
MF
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;
fe41f721
MF
689
690#if 0
54af6227
MF
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;
fe41f721 705#endif
54af6227
MF
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;
fe41f721 725 if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0)
54af6227
MF
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;
fe41f721 762 if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0)
54af6227
MF
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);
fe41f721 1014#if LINUX_VERSION_CODE >= 0x20400
54af6227
MF
1015 info.totalhigh = H2T_4 (info.totalhigh);
1016 info.freehigh = H2T_4 (info.freehigh);
1017 info.mem_unit = H2T_4 (info.mem_unit);
fe41f721 1018#endif
54af6227
MF
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;
fe41f721
MF
1027
1028#if 0
54af6227
MF
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;
fe41f721
MF
1036#endif
1037
54af6227
MF
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;
fe41f721
MF
1091
1092#if 0
54af6227
MF
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;
fe41f721
MF
1134#endif
1135
54af6227
MF
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)
fe41f721 1306 m32rbf_h_gr_set (current_cpu, 0, -errcode);
54af6227 1307 else
fe41f721
MF
1308 m32rbf_h_gr_set (current_cpu, 0, result);
1309 break;
1310 }
fe7f0b01 1311#endif
fe41f721 1312
c906108c
SS
1313 case TRAP_BREAKPOINT:
1314 sim_engine_halt (sd, current_cpu, NULL, pc,
1315 sim_stopped, SIM_SIGTRAP);
1316 break;
1317
16b47b25
NC
1318 case TRAP_FLUSH_CACHE:
1319 /* Do nothing. */
1320 break;
1321
fe41f721
MF
1322 case_default:
1323 default:
c906108c 1324 {
fe41f721
MF
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. */
16b47b25 1328 /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
fe41f721 1329 USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
c906108c
SS
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}
This page took 2.171615 seconds and 5 git commands to generate.