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