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