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