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