1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
3 Contributed by Axis Communications.
5 This file is part of the GNU simulators.
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.
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.
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/>. */
21 #include "sim-options.h"
23 /* FIXME: get rid of targ-vals.h usage everywhere else. */
35 #ifdef HAVE_SYS_PARAM_H
36 #include <sys/param.h>
38 #ifdef HAVE_SYS_STAT_H
41 /* For PATH_MAX, originally. */
46 /* From ld/sysdep.h. */
48 # define SIM_PATHMAX PATH_MAX
51 # define SIM_PATHMAX MAXPATHLEN
53 # define SIM_PATHMAX 1024
57 /* The verbatim values are from asm-cris/unistd.h. */
59 #define TARGET_SYS_exit 1
60 #define TARGET_SYS_read 3
61 #define TARGET_SYS_write 4
62 #define TARGET_SYS_open 5
63 #define TARGET_SYS_close 6
64 #define TARGET_SYS_unlink 10
65 #define TARGET_SYS_time 13
66 #define TARGET_SYS_lseek 19
67 #define TARGET_SYS_getpid 20
68 #define TARGET_SYS_access 33
69 #define TARGET_SYS_kill 37
70 #define TARGET_SYS_rename 38
71 #define TARGET_SYS_pipe 42
72 #define TARGET_SYS_brk 45
73 #define TARGET_SYS_ioctl 54
74 #define TARGET_SYS_fcntl 55
75 #define TARGET_SYS_getppid 64
76 #define TARGET_SYS_setrlimit 75
77 #define TARGET_SYS_gettimeofday 78
78 #define TARGET_SYS_readlink 85
79 #define TARGET_SYS_munmap 91
80 #define TARGET_SYS_truncate 92
81 #define TARGET_SYS_ftruncate 93
82 #define TARGET_SYS_socketcall 102
83 #define TARGET_SYS_stat 106
84 #define TARGET_SYS_fstat 108
85 #define TARGET_SYS_wait4 114
86 #define TARGET_SYS_sigreturn 119
87 #define TARGET_SYS_clone 120
88 #define TARGET_SYS_uname 122
89 #define TARGET_SYS_mprotect 125
90 #define TARGET_SYS_llseek 140
91 #define TARGET_SYS_writev 146
92 #define TARGET_SYS__sysctl 149
93 #define TARGET_SYS_sched_setparam 154
94 #define TARGET_SYS_sched_getparam 155
95 #define TARGET_SYS_sched_setscheduler 156
96 #define TARGET_SYS_sched_getscheduler 157
97 #define TARGET_SYS_sched_yield 158
98 #define TARGET_SYS_sched_get_priority_max 159
99 #define TARGET_SYS_sched_get_priority_min 160
100 #define TARGET_SYS_mremap 163
101 #define TARGET_SYS_poll 168
102 #define TARGET_SYS_rt_sigaction 174
103 #define TARGET_SYS_rt_sigprocmask 175
104 #define TARGET_SYS_rt_sigsuspend 179
105 #define TARGET_SYS_getcwd 183
106 #define TARGET_SYS_ugetrlimit 191
107 #define TARGET_SYS_mmap2 192
108 #define TARGET_SYS_stat64 195
109 #define TARGET_SYS_lstat64 196
110 #define TARGET_SYS_fstat64 197
111 #define TARGET_SYS_geteuid32 201
112 #define TARGET_SYS_getuid32 199
113 #define TARGET_SYS_getegid32 202
114 #define TARGET_SYS_getgid32 200
115 #define TARGET_SYS_fcntl64 221
117 #define TARGET_PROT_READ 0x1
118 #define TARGET_PROT_WRITE 0x2
119 #define TARGET_PROT_EXEC 0x4
120 #define TARGET_PROT_NONE 0x0
122 #define TARGET_MAP_SHARED 0x01
123 #define TARGET_MAP_PRIVATE 0x02
124 #define TARGET_MAP_TYPE 0x0f
125 #define TARGET_MAP_FIXED 0x10
126 #define TARGET_MAP_ANONYMOUS 0x20
127 #define TARGET_MAP_DENYWRITE 0x800
129 #define TARGET_CTL_KERN 1
130 #define TARGET_CTL_VM 2
131 #define TARGET_CTL_NET 3
132 #define TARGET_CTL_PROC 4
133 #define TARGET_CTL_FS 5
134 #define TARGET_CTL_DEBUG 6
135 #define TARGET_CTL_DEV 7
136 #define TARGET_CTL_BUS 8
137 #define TARGET_CTL_ABI 9
139 #define TARGET_CTL_KERN_VERSION 4
142 #define TARGET_MREMAP_MAYMOVE 1
143 #define TARGET_MREMAP_FIXED 2
145 #define TARGET_TCGETS 0x5401
147 #define TARGET_UTSNAME "#38 Sun Apr 1 00:00:00 MET 2001"
149 /* Seconds since the above date + 10 minutes. */
150 #define TARGET_EPOCH 986080200
152 /* Milliseconds since start of run. We use the number of syscalls to
153 avoid introducing noise in the execution time. */
154 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
156 /* Seconds as in time(2). */
157 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
159 #define TARGET_SCHED_OTHER 0
161 #define TARGET_RLIMIT_STACK 3
162 #define TARGET_RLIMIT_NOFILE 7
164 #define SIM_TARGET_MAX_THREADS 64
165 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
167 /* From linux/sched.h. */
168 #define TARGET_CSIGNAL 0x000000ff
169 #define TARGET_CLONE_VM 0x00000100
170 #define TARGET_CLONE_FS 0x00000200
171 #define TARGET_CLONE_FILES 0x00000400
172 #define TARGET_CLONE_SIGHAND 0x00000800
173 #define TARGET_CLONE_PID 0x00001000
174 #define TARGET_CLONE_PTRACE 0x00002000
175 #define TARGET_CLONE_VFORK 0x00004000
176 #define TARGET_CLONE_PARENT 0x00008000
177 #define TARGET_CLONE_THREAD 0x00010000
178 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
180 /* From asm-cris/poll.h. */
181 #define TARGET_POLLIN 1
183 /* From asm-cris/signal.h. */
184 #define TARGET_SIG_BLOCK 0
185 #define TARGET_SIG_UNBLOCK 1
186 #define TARGET_SIG_SETMASK 2
188 #define TARGET_SIG_DFL 0
189 #define TARGET_SIG_IGN 1
190 #define TARGET_SIG_ERR ((USI)-1)
192 #define TARGET_SIGHUP 1
193 #define TARGET_SIGINT 2
194 #define TARGET_SIGQUIT 3
195 #define TARGET_SIGILL 4
196 #define TARGET_SIGTRAP 5
197 #define TARGET_SIGABRT 6
198 #define TARGET_SIGIOT 6
199 #define TARGET_SIGBUS 7
200 #define TARGET_SIGFPE 8
201 #define TARGET_SIGKILL 9
202 #define TARGET_SIGUSR1 10
203 #define TARGET_SIGSEGV 11
204 #define TARGET_SIGUSR2 12
205 #define TARGET_SIGPIPE 13
206 #define TARGET_SIGALRM 14
207 #define TARGET_SIGTERM 15
208 #define TARGET_SIGSTKFLT 16
209 #define TARGET_SIGCHLD 17
210 #define TARGET_SIGCONT 18
211 #define TARGET_SIGSTOP 19
212 #define TARGET_SIGTSTP 20
213 #define TARGET_SIGTTIN 21
214 #define TARGET_SIGTTOU 22
215 #define TARGET_SIGURG 23
216 #define TARGET_SIGXCPU 24
217 #define TARGET_SIGXFSZ 25
218 #define TARGET_SIGVTALRM 26
219 #define TARGET_SIGPROF 27
220 #define TARGET_SIGWINCH 28
221 #define TARGET_SIGIO 29
222 #define TARGET_SIGPOLL SIGIO
223 /* Actually commented out in the kernel header. */
224 #define TARGET_SIGLOST 29
225 #define TARGET_SIGPWR 30
226 #define TARGET_SIGSYS 31
228 /* From include/asm-cris/signal.h. */
229 #define TARGET_SA_NOCLDSTOP 0x00000001
230 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
231 #define TARGET_SA_SIGINFO 0x00000004
232 #define TARGET_SA_ONSTACK 0x08000000
233 #define TARGET_SA_RESTART 0x10000000
234 #define TARGET_SA_NODEFER 0x40000000
235 #define TARGET_SA_RESETHAND 0x80000000
236 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
237 #define TARGET_SA_RESTORER 0x04000000
239 /* From linux/wait.h. */
240 #define TARGET_WNOHANG 1
241 #define TARGET_WUNTRACED 2
242 #define TARGET___WNOTHREAD 0x20000000
243 #define TARGET___WALL 0x40000000
244 #define TARGET___WCLONE 0x80000000
246 /* From linux/limits.h. */
247 #define TARGET_PIPE_BUF 4096
250 #define TARGET_R_OK 4
251 #define TARGET_W_OK 2
252 #define TARGET_X_OK 1
253 #define TARGET_F_OK 0
255 static const char stat_map
[] =
256 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
257 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
258 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
261 static const CB_TARGET_DEFS_MAP syscall_map
[] =
263 { CB_SYS_open
, TARGET_SYS_open
},
264 { CB_SYS_close
, TARGET_SYS_close
},
265 { CB_SYS_read
, TARGET_SYS_read
},
266 { CB_SYS_write
, TARGET_SYS_write
},
267 { CB_SYS_lseek
, TARGET_SYS_lseek
},
268 { CB_SYS_unlink
, TARGET_SYS_unlink
},
269 { CB_SYS_getpid
, TARGET_SYS_getpid
},
270 { CB_SYS_fstat
, TARGET_SYS_fstat64
},
271 { CB_SYS_lstat
, TARGET_SYS_lstat64
},
272 { CB_SYS_stat
, TARGET_SYS_stat64
},
273 { CB_SYS_pipe
, TARGET_SYS_pipe
},
274 { CB_SYS_rename
, TARGET_SYS_rename
},
275 { CB_SYS_truncate
, TARGET_SYS_truncate
},
276 { CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
280 /* An older, 32-bit-only stat mapping. */
281 static const char stat32_map
[] =
282 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
283 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
284 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
286 /* Map for calls using the 32-bit struct stat. Primarily used by the
287 newlib Linux mapping. */
288 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
290 { CB_SYS_fstat
, TARGET_SYS_fstat
},
291 { CB_SYS_stat
, TARGET_SYS_stat
},
295 /* Giving the true value for the running sim process will lead to
296 non-time-invariant behavior. */
297 #define TARGET_PID 42
299 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
300 we did, we'd still don't get a register number with the "16" offset. */
301 #define TARGET_SRP_REGNUM (16+11)
303 /* Extracted by applying
304 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
305 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
306 adjusting the synonyms. */
308 static const CB_TARGET_DEFS_MAP errno_map
[] =
416 { ENAMETOOLONG
, 36 },
575 { EDESTADDRREQ
, 89 },
586 #ifdef EPROTONOSUPPORT
587 { EPROTONOSUPPORT
, 93 },
589 #ifdef ESOCKTNOSUPPORT
590 { ESOCKTNOSUPPORT
, 94 },
596 { EPFNOSUPPORT
, 96 },
599 { EAFNOSUPPORT
, 97 },
605 { EADDRNOTAVAIL
, 99 },
611 { ENETUNREACH
, 101 },
617 { ECONNABORTED
, 103 },
635 { ETOOMANYREFS
, 109 },
641 { ECONNREFUSED
, 111 },
647 { EHOSTUNREACH
, 113 },
653 { EINPROGRESS
, 115 },
680 { EMEDIUMTYPE
, 124 },
685 /* Extracted by applying
686 perl -ne 'if ($_ =~ /^#define/) { split;
687 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
688 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
689 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
690 installation and removing synonyms and unnecessary items. Don't
691 forget the end-marker. */
693 /* These we treat specially, as they're used in the fcntl F_GETFL
694 syscall. For consistency, open_map is also manually edited to use
696 #define TARGET_O_ACCMODE 0x3
697 #define TARGET_O_RDONLY 0x0
698 #define TARGET_O_WRONLY 0x1
700 static const CB_TARGET_DEFS_MAP open_map
[] = {
702 { O_ACCMODE
, TARGET_O_ACCMODE
},
705 { O_RDONLY
, TARGET_O_RDONLY
},
708 { O_WRONLY
, TARGET_O_WRONLY
},
729 { O_NONBLOCK
, 0x800 },
741 { O_DIRECT
, 0x4000 },
744 { O_LARGEFILE
, 0x8000 },
747 { O_DIRECTORY
, 0x10000 },
750 { O_NOFOLLOW
, 0x20000 },
755 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
756 static SIM_CPU
*current_cpu_for_cb_callback
;
758 static int syscall_read_mem (host_callback
*, struct cb_syscall
*,
759 unsigned long, char *, int);
760 static int syscall_write_mem (host_callback
*, struct cb_syscall
*,
761 unsigned long, const char *, int);
762 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
764 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
766 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
768 static void dump_statistics (SIM_CPU
*current_cpu
);
769 static void make_first_thread (SIM_CPU
*current_cpu
);
771 /* Read/write functions for system call interface. */
774 syscall_read_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
775 struct cb_syscall
*sc
,
776 unsigned long taddr
, char *buf
, int bytes
)
778 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
779 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
781 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
785 syscall_write_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
786 struct cb_syscall
*sc
,
787 unsigned long taddr
, const char *buf
, int bytes
)
789 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
790 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
792 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
795 /* When we risk running self-modified code (as in trampolines), this is
796 called from special-case insns. The silicon CRIS CPU:s have enough
797 cache snooping implemented making this a simulator-only issue. Tests:
798 gcc.c-torture/execute/931002-1.c execution, -O3 -g
799 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
802 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
803 USI pc ATTRIBUTE_UNUSED
)
805 SIM_DESC sd
= CPU_STATE (current_cpu
);
808 if (USING_SCACHE_P (sd
))
809 scache_flush_cpu (current_cpu
);
813 /* Output statistics at the end of a run. */
815 dump_statistics (SIM_CPU
*current_cpu
)
817 SIM_DESC sd
= CPU_STATE (current_cpu
);
818 CRIS_MISC_PROFILE
*profp
819 = CPU_CRIS_MISC_PROFILE (current_cpu
);
820 unsigned64 total
= profp
->basic_cycle_count
;
821 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
823 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
824 what's included in the "total" count only. */
825 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
826 & FLAG_CRIS_MISC_PROFILE_ALL
)
828 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
831 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
833 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
834 total
+= profp
->unaligned_mem_dword_count
;
837 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
838 textmsg
= "Schedulable clock cycles, total @: %llu\n";
840 += (profp
->memsrc_stall_count
841 + profp
->memraw_stall_count
842 + profp
->movemsrc_stall_count
843 + profp
->movemdst_stall_count
844 + profp
->mulsrc_stall_count
845 + profp
->jumpsrc_stall_count
846 + profp
->unaligned_mem_dword_count
);
849 case FLAG_CRIS_MISC_PROFILE_ALL
:
850 textmsg
= "All accounted clock cycles, total @: %llu\n";
852 += (profp
->memsrc_stall_count
853 + profp
->memraw_stall_count
854 + profp
->movemsrc_stall_count
855 + profp
->movemdst_stall_count
856 + profp
->movemaddr_stall_count
857 + profp
->mulsrc_stall_count
858 + profp
->jumpsrc_stall_count
859 + profp
->branch_stall_count
860 + profp
->jumptarget_stall_count
861 + profp
->unaligned_mem_dword_count
);
868 "Internal inconsistency at %s:%d",
870 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
871 sim_stopped
, SIM_SIGILL
);
874 /* Historically, these messages have gone to stderr, so we'll keep it
875 that way. It's also easier to then tell it from normal program
876 output. FIXME: Add redirect option like "run -e file". */
877 sim_io_eprintf (sd
, textmsg
, total
);
879 /* For v32, unaligned_mem_dword_count should always be 0. For
880 v10, memsrc_stall_count should always be 0. */
881 sim_io_eprintf (sd
, "Memory source stall cycles: %llu\n",
882 (unsigned long long) (profp
->memsrc_stall_count
883 + profp
->unaligned_mem_dword_count
));
884 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %llu\n",
885 (unsigned long long) profp
->memraw_stall_count
);
886 sim_io_eprintf (sd
, "Movem source stall cycles: %llu\n",
887 (unsigned long long) profp
->movemsrc_stall_count
);
888 sim_io_eprintf (sd
, "Movem destination stall cycles: %llu\n",
889 (unsigned long long) profp
->movemdst_stall_count
);
890 sim_io_eprintf (sd
, "Movem address stall cycles: %llu\n",
891 (unsigned long long) profp
->movemaddr_stall_count
);
892 sim_io_eprintf (sd
, "Multiplication source stall cycles: %llu\n",
893 (unsigned long long) profp
->mulsrc_stall_count
);
894 sim_io_eprintf (sd
, "Jump source stall cycles: %llu\n",
895 (unsigned long long) profp
->jumpsrc_stall_count
);
896 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %llu\n",
897 (unsigned long long) profp
->branch_stall_count
);
898 sim_io_eprintf (sd
, "Jump target stall cycles: %llu\n",
899 (unsigned long long) profp
->jumptarget_stall_count
);
902 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
903 Return 1 if a overlap detected, 0 otherwise. */
906 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
907 struct cris_sim_mmapped_page
**rootp
,
910 struct cris_sim_mmapped_page
*mapp
;
912 if (len
== 0 || (len
& 8191))
915 /* Iterate over the reverse-address sorted pages until we find a page in
916 or lower than the checked area. */
917 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
918 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
924 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
925 Return 1 if the whole area is mapped, 0 otherwise. */
928 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
929 struct cris_sim_mmapped_page
**rootp
,
932 struct cris_sim_mmapped_page
*mapp
;
934 if (len
== 0 || (len
& 8191))
937 /* Iterate over the reverse-address sorted pages until we find a page
938 lower than the checked area. */
939 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
940 if (addr
== mapp
->addr
&& len
== 8192)
942 else if (addr
+ len
> mapp
->addr
)
948 /* Debug helper; to be run from gdb. */
951 cris_dump_map (SIM_CPU
*current_cpu
)
953 struct cris_sim_mmapped_page
*mapp
;
956 for (mapp
= current_cpu
->highest_mmapped_page
,
957 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
958 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
962 if (mapp
->addr
!= start
- 8192)
964 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
965 end
= mapp
->addr
+ 8191;
971 if (current_cpu
->highest_mmapped_page
!= NULL
)
972 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
975 /* Create mmapped memory. */
978 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
981 struct cris_sim_mmapped_page
*mapp
;
982 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
983 USI new_addr
= 0x40000000;
988 new_addr
= rootp
[0]->addr
+ 8192;
995 /* Which is better: return an error for this, or just round it up? */
998 /* Do a recursive call for each page in the request. */
999 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
1000 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
1007 mapp
!= NULL
&& mapp
->addr
> new_addr
;
1009 higher_prevp
= &mapp
->prev
;
1011 /* Allocate the new page, on the next higher page from the last one
1012 allocated, and link in the new descriptor before previous ones. */
1013 mapp
= malloc (sizeof (*mapp
));
1016 return (USI
) -ENOMEM
;
1018 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1022 mapp
->addr
= new_addr
;
1023 mapp
->prev
= *higher_prevp
;
1024 *higher_prevp
= mapp
;
1029 /* Unmap one or more pages. */
1032 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1035 struct cris_sim_mmapped_page
*mapp
;
1036 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1043 /* Which is better: return an error for this, or just round it up? */
1046 /* Loop backwards to make each call is O(1) over the number of pages
1047 allocated, if we're unmapping from the high end of the pages. */
1048 for (page_addr
= addr
+ len
- 8192;
1051 if (unmap_pages (sd
, rootp
, page_addr
, 8192) != 0)
1057 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1058 higher_prevp
= &mapp
->prev
;
1060 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1063 *higher_prevp
= mapp
->prev
;
1064 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1069 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1072 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1074 SIM_DESC sd
= CPU_STATE (current_cpu
);
1076 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1080 /* Handlers from the CGEN description that should not be called. */
1083 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1084 UINT srcreg ATTRIBUTE_UNUSED
,
1085 USI dstreg ATTRIBUTE_UNUSED
)
1091 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1092 UINT index ATTRIBUTE_UNUSED
,
1093 USI page ATTRIBUTE_UNUSED
,
1094 USI newval ATTRIBUTE_UNUSED
)
1100 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1101 UINT index ATTRIBUTE_UNUSED
,
1102 USI page ATTRIBUTE_UNUSED
)
1107 /* Swap one context for another. */
1110 schedule (SIM_CPU
*current_cpu
, int next
)
1112 /* Need to mark context-switches in the trace output. */
1113 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1114 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1115 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1118 /* Copy the current context (if there is one) to its slot. */
1119 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1120 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1121 ¤t_cpu
->cpu_data_placeholder
,
1122 current_cpu
->thread_cpu_data_size
);
1124 /* Copy the new context from its slot. */
1125 memcpy (¤t_cpu
->cpu_data_placeholder
,
1126 current_cpu
->thread_data
[next
].cpu_context
,
1127 current_cpu
->thread_cpu_data_size
);
1129 /* Update needed stuff to indicate the new context. */
1130 current_cpu
->threadno
= next
;
1132 /* Handle pending signals. */
1133 if (current_cpu
->thread_data
[next
].sigpending
1134 /* We don't run nested signal handlers. This means that pause(2)
1135 and sigsuspend(2) do not work in sighandlers, but that
1136 shouldn't be too hard a restriction. It also greatly
1137 simplifies the code. */
1138 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1142 /* See if there's really a pending, non-blocked handler. We don't
1143 queue signals, so just use the first one in ascending order. */
1144 for (sig
= 0; sig
< 64; sig
++)
1145 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1146 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1152 USI pc
= sim_pc_get (current_cpu
);
1154 /* It's simpler to save the CPU context inside the simulator
1155 than on the stack. */
1156 current_cpu
->thread_data
[next
].cpu_context_atsignal
1158 ->make_thread_cpu_data
) (current_cpu
,
1159 current_cpu
->thread_data
[next
]
1162 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1163 sp
= bfd_getl32 (regbuf
);
1165 /* Make sure we have an aligned stack. */
1168 /* Make room for the signal frame, aligned. FIXME: Check that
1169 the memory exists, map it in if absent. (BTW, should also
1170 implement on-access automatic stack allocation). */
1173 /* This isn't the same signal frame as the kernel uses, because
1174 we don't want to bother getting all registers on and off the
1177 /* First, we store the currently blocked signals. */
1179 for (i
= 0; i
< 32; i
++)
1181 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1182 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1184 for (i
= 0; i
< 31; i
++)
1186 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1187 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1189 /* Then, the actual instructions. This is CPU-specific, but we
1190 use instructions from the common subset for v10 and v32 which
1191 should be safe for the time being but could be parametrized
1193 /* MOVU.W [PC+],R9. */
1194 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1195 /* .WORD TARGET_SYS_sigreturn. */
1196 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1197 TARGET_SYS_sigreturn
);
1199 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1201 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1202 instruction. Still, it doesn't matter because v10 has no
1203 delay slot for BREAK so it will not be executed). */
1204 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1206 /* Modify registers to hold the right values for the sighandler
1207 context: updated stackpointer and return address pointing to
1208 the sigreturn stub. */
1209 bfd_putl32 (sp
, regbuf
);
1210 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1211 bfd_putl32 (sp
+ 8, regbuf
);
1212 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1215 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1217 /* Block this signal (for the duration of the sighandler). */
1218 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1220 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1221 bfd_putl32 (sig
, regbuf
);
1222 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1225 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1226 needed all this for, specifies a SA_SIGINFO call but treats it
1227 like an ordinary sighandler; only the signal number argument is
1228 inspected. To make future need to implement SA_SIGINFO
1229 correctly possible, we set the siginfo argument register to a
1230 magic (hopefully non-address) number. (NB: then, you should
1231 just need to pass the siginfo argument; it seems you probably
1232 don't need to implement the specific rt_sigreturn.) */
1233 bfd_putl32 (0xbad5161f, regbuf
);
1234 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1237 /* The third argument is unused and the kernel sets it to 0. */
1238 bfd_putl32 (0, regbuf
);
1239 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1244 /* No, there actually was no pending signal for this thread. Reset
1246 current_cpu
->thread_data
[next
].sigpending
= 0;
1250 /* Reschedule the simplest possible way until something else is absolutely
1252 - A. Find the next process (round-robin) that doesn't have at_syscall
1254 - B. If there is none, just run the next process, round-robin.
1255 - Clear at_syscall for the current process. */
1258 reschedule (SIM_CPU
*current_cpu
)
1262 /* Iterate over all thread slots, because after a few thread creations
1263 and exits, we don't know where the live ones are. */
1264 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1265 i
!= current_cpu
->threadno
;
1266 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1267 if (current_cpu
->thread_data
[i
].cpu_context
1268 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1270 schedule (current_cpu
, i
);
1274 /* Pick any next live thread. */
1275 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1276 i
!= current_cpu
->threadno
;
1277 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1278 if (current_cpu
->thread_data
[i
].cpu_context
)
1280 schedule (current_cpu
, i
);
1284 /* More than one live thread, but we couldn't find the next one? */
1288 /* Set up everything to receive (or IGN) an incoming signal to the
1292 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1295 USI pc
= sim_pc_get (current_cpu
);
1297 /* Find the thread index of the pid. */
1298 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1299 /* Apparently it's ok to send signals to zombies (so a check for
1300 current_cpu->thread_data[i].cpu_context != NULL would be
1302 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1305 switch (current_cpu
->sighandler
[sig
])
1307 case TARGET_SIG_DFL
:
1310 /* The following according to the glibc
1311 documentation. (The kernel code has non-obvious
1312 execution paths.) */
1315 case TARGET_SIGSEGV
:
1317 case TARGET_SIGABRT
:
1318 case TARGET_SIGTRAP
:
1321 case TARGET_SIGTERM
:
1323 case TARGET_SIGQUIT
:
1324 case TARGET_SIGKILL
:
1327 case TARGET_SIGALRM
:
1328 case TARGET_SIGVTALRM
:
1329 case TARGET_SIGPROF
:
1330 case TARGET_SIGSTOP
:
1332 case TARGET_SIGPIPE
:
1333 case TARGET_SIGLOST
:
1334 case TARGET_SIGXCPU
:
1335 case TARGET_SIGXFSZ
:
1336 case TARGET_SIGUSR1
:
1337 case TARGET_SIGUSR2
:
1338 sim_io_eprintf (CPU_STATE (current_cpu
),
1339 "Exiting pid %d due to signal %d\n",
1341 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1342 NULL
, pc
, sim_stopped
,
1343 sig
== TARGET_SIGABRT
1344 ? SIM_SIGABRT
: SIM_SIGILL
);
1347 /* The default for all other signals is to be ignored. */
1352 case TARGET_SIG_IGN
:
1355 case TARGET_SIGKILL
:
1356 case TARGET_SIGSTOP
:
1357 /* Can't ignore these signals. */
1358 sim_io_eprintf (CPU_STATE (current_cpu
),
1359 "Exiting pid %d due to signal %d\n",
1361 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1362 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1371 /* Mark the signal as pending, making schedule () check
1372 closer. The signal will be handled when the thread is
1373 scheduled and the signal is unblocked. */
1374 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1375 current_cpu
->thread_data
[i
].sigpending
= 1;
1380 sim_io_eprintf (CPU_STATE (current_cpu
),
1381 "Unimplemented signal: %d\n", sig
);
1382 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1383 sim_stopped
, SIM_SIGILL
);
1388 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1392 /* Make the vector and the first item, the main thread. */
1395 make_first_thread (SIM_CPU
*current_cpu
)
1397 current_cpu
->thread_data
1399 SIM_TARGET_MAX_THREADS
1400 * sizeof (current_cpu
->thread_data
[0]));
1401 current_cpu
->thread_data
[0].cpu_context
1402 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1404 ->cpu_data_placeholder
);
1405 current_cpu
->thread_data
[0].parent_threadid
= -1;
1407 /* For good measure. */
1408 if (TARGET_SIG_DFL
!= 0)
1412 /* Handle unknown system calls. Returns (if it does) the syscall
1416 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1418 SIM_DESC sd
= CPU_STATE (current_cpu
);
1419 host_callback
*cb
= STATE_CALLBACK (sd
);
1421 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1422 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1427 sim_io_evprintf (sd
, s
, ap
);
1430 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1431 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1434 return -cb_host_to_target_errno (cb
, ENOSYS
);
1437 /* Main function: the handler of the "break 13" syscall insn. */
1440 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1441 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1445 SIM_DESC sd
= CPU_STATE (current_cpu
);
1446 host_callback
*cb
= STATE_CALLBACK (sd
);
1448 int threadno
= current_cpu
->threadno
;
1450 current_cpu
->syscalls
++;
1452 CB_SYSCALL_INIT (&s
);
1458 if (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0)
1460 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1461 & FLAG_CRIS_MISC_PROFILE_ALL
)
1462 dump_statistics (current_cpu
);
1463 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1467 s
.p2
= (PTR
) current_cpu
;
1468 s
.read_mem
= syscall_read_mem
;
1469 s
.write_mem
= syscall_write_mem
;
1471 current_cpu_for_cb_callback
= current_cpu
;
1473 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1476 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1478 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1481 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1483 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1485 /* If the generic simulator call said ENOSYS, then let's try the
1486 ones we know ourselves.
1488 The convention is to provide *very limited* functionality on an
1489 as-needed basis, only what's covered by the test-suite, tests
1490 added when functionality changes and abort with a descriptive
1491 message for *everything* else. Where there's no test-case, we
1496 /* It's a pretty safe bet that the "old setup() system call"
1497 number will not be re-used; we can't say the same for higher
1498 numbers. We treat this simulator-generated call as "wait
1499 forever"; we re-run this insn. The wait is ended by a
1500 callback. Sanity check that this is the reason we got
1502 if (current_cpu
->thread_data
== NULL
1503 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1504 goto unimplemented_syscall
;
1506 sim_pc_set (current_cpu
, pc
);
1510 case TARGET_SYS_fcntl64
:
1511 case TARGET_SYS_fcntl
:
1516 Glibc checks stdin, stdout and stderr fd:s for
1517 close-on-exec security sanity. We just need to provide a
1518 OK return value. If we really need to have a
1519 close-on-exec flag true, we could just do a real fcntl
1525 /* F_SETFD. Just ignore attempts to set the close-on-exec
1531 /* F_GETFL. Check for the special case for open+fdopen. */
1532 if (current_cpu
->last_syscall
== TARGET_SYS_open
1533 && arg1
== current_cpu
->last_open_fd
)
1535 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1540 /* Because we can't freopen fd:s 0, 1, 2 to mean
1541 something else than stdin, stdout and stderr
1542 (sim/common/syscall.c:cb_syscall special cases fd
1543 0, 1 and 2), we know what flags that we can
1544 sanely return for these fd:s. */
1545 retval
= TARGET_O_RDONLY
;
1548 else if (arg1
== 1 || arg1
== 2)
1550 retval
= TARGET_O_WRONLY
;
1555 /* Nothing else is implemented. */
1557 = cris_unknown_syscall (current_cpu
, pc
,
1558 "Unimplemented %s syscall "
1559 "(fd: 0x%lx: cmd: 0x%lx arg: "
1561 callnum
== TARGET_SYS_fcntl
1562 ? "fcntl" : "fcntl64",
1563 (unsigned long) (USI
) arg1
,
1564 (unsigned long) (USI
) arg2
,
1565 (unsigned long) (USI
) arg3
);
1570 case TARGET_SYS_uname
:
1572 /* Fill in a few constants to appease glibc. */
1573 static const char sim_utsname
[6][65] =
1583 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1584 sizeof (sim_utsname
))
1585 != sizeof (sim_utsname
))
1586 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1592 case TARGET_SYS_geteuid32
:
1593 /* We tell the truth with these. Maybe we shouldn't, but it
1594 should match the "stat" information. */
1595 retval
= geteuid ();
1598 case TARGET_SYS_getuid32
:
1602 case TARGET_SYS_getegid32
:
1603 retval
= getegid ();
1606 case TARGET_SYS_getgid32
:
1610 case TARGET_SYS_brk
:
1611 /* Most often, we just return the argument, like the Linux
1616 retval
= current_cpu
->endbrk
;
1617 else if (arg1
<= current_cpu
->endmem
)
1618 current_cpu
->endbrk
= arg1
;
1621 USI new_end
= (arg1
+ 8191) & ~8191;
1623 /* If the simulator wants to brk more than a certain very
1624 large amount, something is wrong. FIXME: Return an error
1625 or abort? Have command-line selectable? */
1626 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1628 current_cpu
->endbrk
= current_cpu
->endmem
;
1629 retval
= current_cpu
->endmem
;
1633 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1634 current_cpu
->endmem
,
1635 new_end
- current_cpu
->endmem
,
1637 current_cpu
->endbrk
= arg1
;
1638 current_cpu
->endmem
= new_end
;
1642 case TARGET_SYS_getpid
:
1643 /* Correct until CLONE_THREAD is implemented. */
1644 retval
= current_cpu
->thread_data
== NULL
1646 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1649 case TARGET_SYS_getppid
:
1650 /* Correct until CLONE_THREAD is implemented. */
1651 retval
= current_cpu
->thread_data
== NULL
1654 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1657 case TARGET_SYS_mmap2
:
1666 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1667 still masked away this bit, so let's just ignore
1669 flags
&= ~TARGET_MAP_DENYWRITE
;
1671 /* If the simulator wants to mmap more than the very large
1672 limit, something is wrong. FIXME: Return an error or
1673 abort? Have command-line selectable? */
1674 if (len
> SIM_MAX_ALLOC_CHUNK
)
1676 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1680 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1682 != (TARGET_PROT_READ
1684 | TARGET_PROT_EXEC
))
1685 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1686 && prot
!= TARGET_PROT_READ
)
1687 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1688 && flags
!= TARGET_MAP_PRIVATE
1689 && flags
!= (TARGET_MAP_ANONYMOUS
1690 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1691 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1692 && flags
!= TARGET_MAP_SHARED
)
1694 && prot
!= TARGET_PROT_READ
1695 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1696 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1697 || (fd
== (USI
) -1 && pgoff
!= 0)
1698 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
))
1699 || ((flags
& TARGET_MAP_FIXED
) == 0
1700 && is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1701 addr
, (len
+ 8191) & ~8191)))
1704 = cris_unknown_syscall (current_cpu
, pc
,
1705 "Unimplemented mmap2 call "
1706 "(0x%lx, 0x%lx, 0x%lx, "
1707 "0x%lx, 0x%lx, 0x%lx)\n",
1708 (unsigned long) arg1
,
1709 (unsigned long) arg2
,
1710 (unsigned long) arg3
,
1711 (unsigned long) arg4
,
1712 (unsigned long) arg5
,
1713 (unsigned long) arg6
);
1716 else if (fd
!= (USI
) -1)
1723 /* A non-aligned argument is allowed for files. */
1724 USI newlen
= (len
+ 8191) & ~8191;
1726 /* We only support read, read|exec, and read|write,
1727 which we should already have checked. Check again
1729 if (prot
!= TARGET_PROT_READ
1730 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1731 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1734 if ((flags
& TARGET_MAP_FIXED
)
1735 && unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1740 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1743 if (newaddr
>= (USI
) -8191)
1746 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1750 /* We were asked for MAP_FIXED, but couldn't. */
1751 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1754 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1756 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1760 /* Find the current position in the file. */
1761 s
.func
= TARGET_SYS_lseek
;
1765 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1772 /* Move to the correct offset in the file. */
1773 s
.func
= TARGET_SYS_lseek
;
1775 s
.arg2
= pgoff
*8192;
1777 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1783 /* Use the standard read callback to read in "len"
1785 s
.func
= TARGET_SYS_read
;
1789 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1792 if ((USI
) s
.result
!= len
)
1795 /* After reading, we need to go back to the previous
1796 position in the file. */
1797 s
.func
= TARGET_SYS_lseek
;
1801 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1803 if (pos
!= (USI
) s
.result
)
1810 USI newlen
= (len
+ 8191) & ~8191;
1813 if ((flags
& TARGET_MAP_FIXED
)
1814 && unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1818 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1821 if (newaddr
>= (USI
) -8191)
1822 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1826 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1829 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1831 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1838 case TARGET_SYS_mprotect
:
1840 /* We only cover the case of linuxthreads mprotecting out
1841 its stack guard page and of dynamic loading mprotecting
1842 away the data (for some reason the whole library, then
1843 mprotects away the data part and mmap-FIX:es it again. */
1848 if (prot
!= TARGET_PROT_NONE
1849 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1850 addr
, (len
+ 8191) & ~8191))
1853 = cris_unknown_syscall (current_cpu
, pc
,
1854 "Unimplemented mprotect call "
1855 "(0x%lx, 0x%lx, 0x%lx)\n",
1856 (unsigned long) arg1
,
1857 (unsigned long) arg2
,
1858 (unsigned long) arg3
);
1862 /* Just ignore this. We could make this equal to munmap,
1863 but then we'd have to make sure no anon mmaps gets this
1864 address before a subsequent MAP_FIXED mmap intended to
1870 case TARGET_SYS_ioctl
:
1872 /* We support only a very limited functionality: checking
1873 stdout with TCGETS to perform the isatty function. The
1874 TCGETS ioctl isn't actually performed or the result used by
1875 an isatty () caller in a "hello, world" program; only the
1876 return value is then used. Maybe we shouldn't care about
1877 the environment of the simulator regarding isatty, but
1878 that's been working before, in the xsim simulator. */
1879 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1880 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1882 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1886 case TARGET_SYS_munmap
:
1891 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1893 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1897 case TARGET_SYS_wait4
:
1905 /* FIXME: We're not properly implementing __WCLONE, and we
1906 don't really need the special casing so we might as well
1907 make this general. */
1908 if ((!(pid
== (USI
) -1
1909 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1912 && (options
== TARGET___WCLONE
1913 || options
== TARGET___WALL
)))
1915 || current_cpu
->thread_data
== NULL
)
1918 = cris_unknown_syscall (current_cpu
, pc
,
1919 "Unimplemented wait4 call "
1920 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1921 (unsigned long) arg1
,
1922 (unsigned long) arg2
,
1923 (unsigned long) arg3
,
1924 (unsigned long) arg4
);
1928 if (pid
== (USI
) -1)
1929 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1931 if (current_cpu
->thread_data
[threadno
].threadid
1932 == current_cpu
->thread_data
[i
].parent_threadid
1933 && current_cpu
->thread_data
[i
].threadid
!= 0
1934 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1936 /* A zombied child. Get the exit value and clear the
1937 zombied entry so it will be reused. */
1938 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1940 ->thread_data
[i
].exitval
);
1942 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1943 memset (¤t_cpu
->thread_data
[i
], 0,
1944 sizeof (current_cpu
->thread_data
[i
]));
1950 /* We're waiting for a specific PID. If we don't find
1951 it zombied on this run, rerun the syscall. */
1952 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1953 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1954 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1957 /* Get the exit value if the caller wants it. */
1958 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1965 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1966 memset (¤t_cpu
->thread_data
[i
], 0,
1967 sizeof (current_cpu
->thread_data
[i
]));
1972 sim_pc_set (current_cpu
, pc
);
1975 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1980 case TARGET_SYS_rt_sigaction
:
1988 __sighandler_t sa_handler;
1989 unsigned long sa_flags;
1990 void (*sa_restorer)(void);
1996 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
1997 current_cpu
->sighandler
[signum
]);
1998 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
1999 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
2001 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2002 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
2003 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
2007 USI target_sa_handler
2008 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2010 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2011 USI target_sa_restorer
2012 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2013 USI target_sa_mask_low
2014 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2015 USI target_sa_mask_high
2016 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2018 /* We won't interrupt a syscall so we won't restart it,
2019 but a signal(2) call ends up syscalling rt_sigaction
2020 with this flag, so we have to handle it. The
2021 sa_restorer field contains garbage when not
2022 TARGET_SA_RESTORER, so don't look at it. For the
2023 time being, we don't nest sighandlers, so we
2024 ignore the sa_mask, which simplifies things. */
2025 if ((target_sa_flags
!= 0
2026 && target_sa_flags
!= TARGET_SA_RESTART
2027 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2028 || target_sa_handler
== 0)
2031 = cris_unknown_syscall (current_cpu
, pc
,
2032 "Unimplemented rt_sigaction "
2035 "[0x%x, 0x%x, 0x%x, "
2036 "{0x%x, 0x%x}], 0x%lx)\n",
2037 (unsigned long) arg1
,
2038 (unsigned long) arg2
,
2043 target_sa_mask_high
,
2044 (unsigned long) arg3
);
2048 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2050 /* Because we may have unblocked signals, one may now be
2051 pending, if there are threads, that is. */
2052 if (current_cpu
->thread_data
)
2053 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2059 case TARGET_SYS_mremap
:
2065 USI new_addr
= arg5
;
2068 if (new_len
== old_len
)
2069 /* The program and/or library is possibly confused but
2070 this is a valid call. Happens with ipps-1.40 on file
2073 else if (new_len
< old_len
)
2075 /* Shrinking is easy. */
2076 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2077 addr
+ new_len
, old_len
- new_len
) != 0)
2078 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2082 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2083 addr
+ old_len
, new_len
- old_len
))
2085 /* If the extension isn't mapped, we can just add it. */
2087 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2088 addr
+ old_len
, new_len
- old_len
);
2090 if (mapped_addr
> (USI
) -8192)
2091 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2095 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2097 /* Create a whole new map and copy the contents
2098 block-by-block there. We ignore the new_addr argument
2101 USI prev_addr
= addr
;
2102 USI prev_len
= old_len
;
2105 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2108 if (mapped_addr
> (USI
) -8192)
2110 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2114 retval
= mapped_addr
;
2117 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2119 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2121 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2122 mapped_addr
, 8192) != 8192)
2126 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2127 prev_addr
, prev_len
) != 0)
2131 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2135 case TARGET_SYS_poll
:
2137 int npollfds
= arg2
;
2153 /* Check that this is the expected poll call from
2154 linuxthreads/manager.c; we don't support anything else.
2155 Remember, fd == 0 isn't supported. */
2157 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2159 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2162 || ((cb
->fstat
) (cb
, fd
, &buf
) != 0
2163 || (buf
.st_mode
& S_IFIFO
) == 0)
2164 || current_cpu
->thread_data
== NULL
)
2167 = cris_unknown_syscall (current_cpu
, pc
,
2168 "Unimplemented poll syscall "
2169 "(0x%lx: [0x%x, 0x%x, x], "
2171 (unsigned long) arg1
, fd
, events
,
2172 (unsigned long) arg2
,
2173 (unsigned long) arg3
);
2179 /* Iterate over threads; find a marker that a writer is
2180 sleeping, waiting for a reader. */
2181 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2182 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2183 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2185 revents
= TARGET_POLLIN
;
2190 /* Timeout decreases with whatever time passed between the
2191 last syscall and this. That's not exactly right for the
2192 first call, but it's close enough that it isn't
2193 worthwhile to complicate matters by making that a special
2196 -= (TARGET_TIME_MS (current_cpu
)
2197 - (current_cpu
->thread_data
[threadno
].last_execution
));
2199 /* Arrange to repeat this syscall until timeout or event,
2200 decreasing timeout at each iteration. */
2201 if (timeout
> 0 && revents
== 0)
2203 bfd_byte timeout_buf
[4];
2205 bfd_putl32 (timeout
, timeout_buf
);
2206 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2207 H_GR_R12
, timeout_buf
, 4);
2208 sim_pc_set (current_cpu
, pc
);
2213 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2218 case TARGET_SYS_time
:
2220 retval
= (int) (*cb
->time
) (cb
, 0L);
2222 /* At time of this writing, CB_SYSCALL_time doesn't do the
2223 part of setting *arg1 to the return value. */
2225 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2229 case TARGET_SYS_gettimeofday
:
2232 USI ts
= TARGET_TIME (current_cpu
);
2233 USI tms
= TARGET_TIME_MS (current_cpu
);
2235 /* First dword is seconds since TARGET_EPOCH. */
2236 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2238 /* Second dword is microseconds. */
2239 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2240 (tms
% 1000) * 1000);
2244 /* Time-zone info is always cleared. */
2245 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2246 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2251 case TARGET_SYS_llseek
:
2253 /* If it fits, tweak parameters to fit the "generic" 32-bit
2254 lseek and use that. */
2262 if (!((offs_hi
== 0 && offs_lo
>= 0)
2263 || (offs_hi
== -1 && offs_lo
< 0)))
2266 = cris_unknown_syscall (current_cpu
, pc
,
2267 "Unimplemented llseek offset,"
2268 " fd %d: 0x%x:0x%x\n",
2269 fd
, (unsigned) arg2
,
2274 s
.func
= TARGET_SYS_lseek
;
2277 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2279 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2281 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2284 retval
= -s
.errcode
;
2287 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2289 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2290 s
.result
< 0 ? -1 : 0);
2295 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2298 void *iov_base; Starting address
2299 size_t iov_len; Number of bytes to transfer
2301 case TARGET_SYS_writev
:
2309 /* We'll ignore strict error-handling and just do multiple write calls. */
2310 for (i
= 0; i
< iovcnt
; i
++)
2314 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2317 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2320 s
.func
= TARGET_SYS_write
;
2325 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2327 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2329 if (sysret
!= iov_len
)
2344 /* This one does have a generic callback function, but at the time
2345 of this writing, cb_syscall does not have code for it, and we
2346 need target-specific code for the threads implementation
2348 case TARGET_SYS_kill
:
2355 /* At kill(2), glibc sets signal masks such that the thread
2356 machinery is initialized. Still, there is and was only
2358 if (current_cpu
->max_threadid
== 0)
2360 if (pid
!= TARGET_PID
)
2362 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2366 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2367 if (sig
== TARGET_SIGABRT
)
2368 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2369 the end-point for failing GCC test-cases. */
2370 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2374 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2375 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2379 /* This will not be reached. */
2383 retval
= deliver_signal (current_cpu
, sig
, pid
);
2387 case TARGET_SYS_rt_sigprocmask
:
2394 if (how
!= TARGET_SIG_BLOCK
2395 && how
!= TARGET_SIG_SETMASK
2396 && how
!= TARGET_SIG_UNBLOCK
)
2399 = cris_unknown_syscall (current_cpu
, pc
,
2400 "Unimplemented rt_sigprocmask "
2401 "syscall (0x%x, 0x%x, 0x%x)\n",
2409 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2412 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2415 /* The sigmask is kept in the per-thread data, so we may
2416 need to create the first one. */
2417 if (current_cpu
->thread_data
== NULL
)
2418 make_first_thread (current_cpu
);
2420 if (how
== TARGET_SIG_SETMASK
)
2421 for (i
= 0; i
< 64; i
++)
2422 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2424 for (i
= 0; i
< 32; i
++)
2425 if ((set_low
& (1 << i
)))
2426 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2427 = (how
!= TARGET_SIG_UNBLOCK
);
2429 for (i
= 0; i
< 31; i
++)
2430 if ((set_high
& (1 << i
)))
2431 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2432 = (how
!= TARGET_SIG_UNBLOCK
);
2434 /* The mask changed, so a signal may be unblocked for
2436 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2444 for (i
= 0; i
< 32; i
++)
2445 if (current_cpu
->thread_data
[threadno
]
2446 .sigdata
[i
+ 1].blocked
)
2448 for (i
= 0; i
< 31; i
++)
2449 if (current_cpu
->thread_data
[threadno
]
2450 .sigdata
[i
+ 33].blocked
)
2453 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2454 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2461 case TARGET_SYS_sigreturn
:
2465 int was_sigsuspended
;
2467 if (current_cpu
->thread_data
== NULL
2468 /* The CPU context is saved with the simulator data, not
2469 on the stack as in the real world. */
2470 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2474 = cris_unknown_syscall (current_cpu
, pc
,
2475 "Invalid sigreturn syscall: "
2476 "no signal handler active "
2477 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2479 (unsigned long) arg1
,
2480 (unsigned long) arg2
,
2481 (unsigned long) arg3
,
2482 (unsigned long) arg4
,
2483 (unsigned long) arg5
,
2484 (unsigned long) arg6
);
2489 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2491 /* Restore the sigmask, either from the stack copy made when
2492 the sighandler was called, or from the saved state
2493 specifically for sigsuspend(2). */
2494 if (was_sigsuspended
)
2496 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2497 for (i
= 0; i
< 64; i
++)
2498 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2499 = current_cpu
->thread_data
[threadno
]
2500 .sigdata
[i
].blocked_suspendsave
;
2508 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2509 H_GR_SP
, regbuf
, 4);
2510 sp
= bfd_getl32 (regbuf
);
2512 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2514 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2516 for (i
= 0; i
< 32; i
++)
2517 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2518 = (set_low
& (1 << i
)) != 0;
2519 for (i
= 0; i
< 31; i
++)
2520 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2521 = (set_high
& (1 << i
)) != 0;
2524 /* The mask changed, so a signal may be unblocked for
2526 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2528 memcpy (¤t_cpu
->cpu_data_placeholder
,
2529 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2530 current_cpu
->thread_cpu_data_size
);
2531 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2532 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2534 /* The return value must come from the saved R10. */
2535 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2536 retval
= bfd_getl32 (regbuf
);
2538 /* We must also break the "sigsuspension loop". */
2539 if (was_sigsuspended
)
2540 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2544 case TARGET_SYS_rt_sigsuspend
:
2552 = cris_unknown_syscall (current_cpu
, pc
,
2553 "Unimplemented rt_sigsuspend syscall"
2554 " arguments (0x%lx, 0x%lx)\n",
2555 (unsigned long) arg1
,
2556 (unsigned long) arg2
);
2560 /* Don't change the signal mask if we're already in
2561 sigsuspend state (i.e. this syscall is a rerun). */
2562 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2565 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2568 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2572 /* Save the current sigmask and insert the user-supplied
2574 for (i
= 0; i
< 32; i
++)
2576 current_cpu
->thread_data
[threadno
]
2577 .sigdata
[i
+ 1].blocked_suspendsave
2578 = current_cpu
->thread_data
[threadno
]
2579 .sigdata
[i
+ 1].blocked
;
2581 current_cpu
->thread_data
[threadno
]
2582 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2584 for (i
= 0; i
< 31; i
++)
2586 current_cpu
->thread_data
[threadno
]
2587 .sigdata
[i
+ 33].blocked_suspendsave
2588 = current_cpu
->thread_data
[threadno
]
2589 .sigdata
[i
+ 33].blocked
;
2590 current_cpu
->thread_data
[threadno
]
2591 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2594 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2596 /* The mask changed, so a signal may be unblocked for
2598 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2601 /* Because we don't use arg1 (newsetp) when this syscall is
2602 rerun, it doesn't matter that we overwrite it with the
2603 (constant) return value. */
2604 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2605 sim_pc_set (current_cpu
, pc
);
2609 /* Add case labels here for other syscalls using the 32-bit
2610 "struct stat", provided they have a corresponding simulator
2611 function of course. */
2612 case TARGET_SYS_stat
:
2613 case TARGET_SYS_fstat
:
2615 /* As long as the infrastructure doesn't cache anything
2616 related to the stat mapping, this trick gets us a dual
2617 "struct stat"-type mapping in the least error-prone way. */
2618 const char *saved_map
= cb
->stat_map
;
2619 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2621 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2622 cb
->stat_map
= stat32_map
;
2624 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2627 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2630 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2632 cb
->stat_map
= saved_map
;
2633 cb
->syscall_map
= saved_syscall_map
;
2637 case TARGET_SYS_getcwd
:
2642 char *cwd
= xmalloc (SIM_PATHMAX
);
2643 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2646 /* FIXME: When and if we support chdir, we need something
2647 a bit more elaborate. */
2648 if (simulator_sysroot
[0] != '\0')
2651 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2652 if (strlen (cwd
) + 1 <= size
)
2654 retval
= strlen (cwd
) + 1;
2655 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2657 != (unsigned int) retval
)
2658 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2664 case TARGET_SYS_access
:
2668 char *pbuf
= xmalloc (SIM_PATHMAX
);
2673 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2675 strcpy (pbuf
, simulator_sysroot
);
2676 o
+= strlen (simulator_sysroot
);
2679 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2682 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2683 if (pbuf
[i
+ o
] == 0)
2687 if (i
+ o
== SIM_PATHMAX
)
2689 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2693 /* Assert that we don't get calls for files for which we
2694 don't have support. */
2695 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2698 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2705 if (access (pbuf
, hmode
) != 0)
2706 retval
= -cb_host_to_target_errno (cb
, errno
);
2714 case TARGET_SYS_readlink
:
2719 char *pbuf
= xmalloc (SIM_PATHMAX
);
2720 char *lbuf
= xmalloc (SIM_PATHMAX
);
2721 char *lbuf_alloc
= lbuf
;
2726 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2728 strcpy (pbuf
, simulator_sysroot
);
2729 o
+= strlen (simulator_sysroot
);
2732 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2735 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2736 if (pbuf
[i
+ o
] == 0)
2740 if (i
+ o
== SIM_PATHMAX
)
2742 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2746 /* Intervene calls for certain files expected in the target
2747 proc file system. */
2748 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2749 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2752 = (STATE_PROG_ARGV (sd
) != NULL
2753 ? *STATE_PROG_ARGV (sd
) : NULL
);
2755 if (argv0
== NULL
|| *argv0
== '.')
2758 = cris_unknown_syscall (current_cpu
, pc
,
2759 "Unimplemented readlink syscall "
2760 "(0x%lx: [\"%s\"], 0x%lx)\n",
2761 (unsigned long) arg1
, pbuf
,
2762 (unsigned long) arg2
);
2765 else if (*argv0
== '/')
2767 if (strncmp (simulator_sysroot
, argv0
,
2768 strlen (simulator_sysroot
)) == 0)
2769 argv0
+= strlen (simulator_sysroot
);
2771 strcpy (lbuf
, argv0
);
2772 nchars
= strlen (argv0
) + 1;
2776 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2777 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2779 if (strncmp (simulator_sysroot
, lbuf
,
2780 strlen (simulator_sysroot
)) == 0)
2781 lbuf
+= strlen (simulator_sysroot
);
2784 strcat (lbuf
, argv0
);
2785 nchars
= strlen (lbuf
) + 1;
2792 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2794 /* We trust that the readlink result returns a *relative*
2795 link, or one already adjusted for the file-path-prefix.
2796 (We can't generally tell the difference, so we go with
2797 the easiest decision; no adjustment.) */
2801 retval
= -cb_host_to_target_errno (cb
, errno
);
2805 if (bufsiz
< nchars
)
2808 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2809 buf
, nchars
) != (unsigned int) nchars
)
2810 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2819 case TARGET_SYS_sched_getscheduler
:
2823 /* FIXME: Search (other) existing threads. */
2824 if (pid
!= 0 && pid
!= TARGET_PID
)
2825 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2827 retval
= TARGET_SCHED_OTHER
;
2831 case TARGET_SYS_sched_getparam
:
2837 struct sched_param {
2841 if (pid
!= 0 && pid
!= TARGET_PID
)
2842 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2845 /* FIXME: Save scheduler setting before threads are
2847 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2848 current_cpu
->thread_data
!= NULL
2850 ->thread_data
[threadno
]
2858 case TARGET_SYS_sched_setparam
:
2863 if ((pid
!= 0 && pid
!= TARGET_PID
)
2864 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2866 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2872 case TARGET_SYS_sched_setscheduler
:
2878 if ((pid
!= 0 && pid
!= TARGET_PID
)
2879 || policy
!= TARGET_SCHED_OTHER
2880 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2882 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2884 /* FIXME: Save scheduler setting to be read in later
2885 sched_getparam calls. */
2890 case TARGET_SYS_sched_yield
:
2891 /* We reschedule to the next thread after a syscall anyway, so
2892 we don't have to do anything here than to set the return
2897 case TARGET_SYS_sched_get_priority_min
:
2898 case TARGET_SYS_sched_get_priority_max
:
2900 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2905 case TARGET_SYS_ugetrlimit
:
2907 unsigned int curlim
, maxlim
;
2908 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2910 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2916 unsigned long rlim_cur;
2917 unsigned long rlim_max;
2919 if (arg1
== TARGET_RLIMIT_NOFILE
)
2921 /* Sadly a very low limit. Better not lie, though. */
2922 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2924 else /* arg1 == TARGET_RLIMIT_STACK */
2926 maxlim
= 0xffffffff;
2929 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2930 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2935 case TARGET_SYS_setrlimit
:
2936 if (arg1
!= TARGET_RLIMIT_STACK
)
2938 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2941 /* FIXME: Save values for future ugetrlimit calls. */
2945 /* Provide a very limited subset of the sysctl functions, and
2946 abort for the rest. */
2947 case TARGET_SYS__sysctl
:
2950 struct __sysctl_args {
2957 unsigned long __unused[4];
2959 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2960 SI name0
= name
== 0
2961 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2962 SI name1
= name
== 0
2963 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2965 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2967 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2969 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2970 SI oldlen
= oldlenp
== 0
2971 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2973 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2975 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2977 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2979 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2980 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2982 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
2983 sizeof (TARGET_UTSNAME
));
2985 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
2986 TARGET_UTSNAME
, oldval
,
2988 != (unsigned int) to_write
)
2989 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2996 = cris_unknown_syscall (current_cpu
, pc
,
2997 "Unimplemented _sysctl syscall "
2998 "(0x%lx: [0x%lx, 0x%lx],"
2999 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3000 (unsigned long) name
,
3001 (unsigned long) name0
,
3002 (unsigned long) name1
,
3003 (unsigned long) nlen
,
3004 (unsigned long) oldval
,
3005 (unsigned long) oldlenp
,
3006 (unsigned long) newval
,
3007 (unsigned long) newlen
);
3011 case TARGET_SYS_exit
:
3013 /* Here for all but the last thread. */
3016 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3018 = (current_cpu
->thread_data
[threadno
].parent_threadid
3020 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3022 /* Any children are now all orphans. */
3023 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3024 if (current_cpu
->thread_data
[i
].parent_threadid
3025 == current_cpu
->thread_data
[threadno
].threadid
)
3026 /* Make getppid(2) return 1 for them, poor little ones. */
3027 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3029 /* Free the cpu context data. When the parent has received
3030 the exit status, we'll clear the entry too. */
3031 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3032 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3033 current_cpu
->m1threads
--;
3036 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3038 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3042 /* Still, we may want to support non-zero exit values. */
3043 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3046 deliver_signal (current_cpu
, exitsig
, ppid
);
3050 case TARGET_SYS_clone
:
3052 int nthreads
= current_cpu
->m1threads
+ 1;
3053 void *thread_cpu_data
;
3054 bfd_byte old_sp_buf
[4];
3056 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3059 /* That's right, the syscall clone arguments are reversed
3060 compared to sys_clone notes in clone(2) and compared to
3061 other Linux ports (i.e. it's the same order as in the
3062 clone(2) libcall). */
3066 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3068 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3072 /* FIXME: Implement the low byte. */
3073 if ((flags
& ~TARGET_CSIGNAL
) !=
3076 | TARGET_CLONE_FILES
3077 | TARGET_CLONE_SIGHAND
)
3081 = cris_unknown_syscall (current_cpu
, pc
,
3082 "Unimplemented clone syscall "
3084 (unsigned long) arg1
,
3085 (unsigned long) arg2
);
3089 if (current_cpu
->thread_data
== NULL
)
3090 make_first_thread (current_cpu
);
3092 /* The created thread will get the new SP and a cleared R10.
3093 Since it's created out of a copy of the old thread and we
3094 don't have a set-register-function that just take the
3095 cpu_data as a parameter, we set the childs values first,
3096 and write back or overwrite them in the parent after the
3098 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3099 H_GR_SP
, old_sp_buf
, 4);
3100 bfd_putl32 (newsp
, sp_buf
);
3101 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3102 H_GR_SP
, sp_buf
, 4);
3103 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3104 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3107 ->make_thread_cpu_data
) (current_cpu
,
3108 ¤t_cpu
->cpu_data_placeholder
);
3109 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3110 H_GR_SP
, old_sp_buf
, 4);
3112 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3114 /* Find an unused slot. After a few threads have been created
3115 and exited, the array is expected to be a bit fragmented.
3116 We don't reuse the first entry, though, that of the
3118 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3119 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3120 /* Don't reuse a zombied entry. */
3121 && current_cpu
->thread_data
[i
].threadid
== 0)
3124 memcpy (¤t_cpu
->thread_data
[i
],
3125 ¤t_cpu
->thread_data
[threadno
],
3126 sizeof (current_cpu
->thread_data
[i
]));
3127 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3128 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3129 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3130 current_cpu
->thread_data
[i
].parent_threadid
3131 = current_cpu
->thread_data
[threadno
].threadid
;
3132 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3133 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3134 current_cpu
->thread_data
[i
].at_syscall
= 0;
3135 current_cpu
->thread_data
[i
].sigpending
= 0;
3136 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3137 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3138 current_cpu
->m1threads
= nthreads
;
3142 /* Better watch these in case they do something necessary. */
3143 case TARGET_SYS_socketcall
:
3144 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3147 unimplemented_syscall
:
3150 = cris_unknown_syscall (current_cpu
, pc
,
3151 "Unimplemented syscall: %d "
3152 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3153 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3158 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3159 if (callnum
== TARGET_SYS_open
)
3161 current_cpu
->last_open_fd
= retval
;
3162 current_cpu
->last_open_flags
= arg2
;
3165 current_cpu
->last_syscall
= callnum
;
3167 /* A system call is a rescheduling point. For the time being, we don't
3168 reschedule anywhere else. */
3169 if (current_cpu
->m1threads
!= 0
3170 /* We need to schedule off from an exiting thread that is the
3172 || (current_cpu
->thread_data
!= NULL
3173 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3175 bfd_byte retval_buf
[4];
3177 current_cpu
->thread_data
[threadno
].last_execution
3178 = TARGET_TIME_MS (current_cpu
);
3179 bfd_putl32 (retval
, retval_buf
);
3180 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3182 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3183 reschedule (current_cpu
);
3185 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3186 retval
= bfd_getl32 (retval_buf
);
3192 /* Callback from simulator write saying that the pipe at (reader, writer)
3193 is now non-empty (so the writer should wait until the pipe is empty, at
3194 least not write to this or any other pipe). Simplest is to just wait
3195 until the pipe is empty. */
3198 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3199 int reader
, int writer
)
3201 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3202 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3204 /* It's the current thread: we just have to re-run the current
3205 syscall instruction (presumably "break 13") and change the syscall
3206 to the special simulator-wait code. Oh, and set a marker that
3207 we're waiting, so we can disambiguate the special call from a
3210 This function may be called multiple times between cris_pipe_empty,
3211 but we must avoid e.g. decreasing PC every time. Check fd markers
3213 if (cpu
->thread_data
== NULL
)
3215 sim_io_eprintf (CPU_STATE (cpu
),
3216 "Terminating simulation due to writing pipe rd:wr %d:%d"
3217 " from one single thread\n", reader
, writer
);
3218 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3219 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3221 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3223 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3224 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3225 /* FIXME: We really shouldn't change registers other than R10 in
3226 syscalls (like R9), here or elsewhere. */
3227 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3228 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3232 /* Callback from simulator close or read call saying that the pipe at
3233 (reader, writer) is now empty (so the writer can write again, perhaps
3234 leave a waiting state). If there are bytes remaining, they couldn't be
3235 consumed (perhaps due to the pipe closing). */
3238 cris_pipe_empty (host_callback
*cb
,
3243 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3244 bfd_byte r10_buf
[4];
3246 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3248 /* We need to find the thread that waits for this pipe. */
3249 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3250 if (cpu
->thread_data
[i
].cpu_context
3251 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3255 /* Temporarily switch to this cpu context, so we can change the
3256 PC by ordinary calls. */
3258 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3259 &cpu
->cpu_data_placeholder
,
3260 cpu
->thread_cpu_data_size
);
3261 memcpy (&cpu
->cpu_data_placeholder
,
3262 cpu
->thread_data
[i
].cpu_context
,
3263 cpu
->thread_cpu_data_size
);
3265 /* The return value is supposed to contain the number of
3266 written bytes, which is the number of bytes requested and
3267 returned at the write call. You might think the right
3268 thing is to adjust the return-value to be only the
3269 *consumed* number of bytes, but it isn't. We're only
3270 called if the pipe buffer is fully consumed or it is being
3271 closed, possibly with remaining bytes. For the latter
3272 case, the writer is still supposed to see success for
3273 PIPE_BUF bytes (a constant which we happen to know and is
3274 unlikely to change). The return value may also be a
3275 negative number; an error value. This case is covered
3276 because "remaining" is always >= 0. */
3277 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3278 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3279 if (retval
- remaining
> TARGET_PIPE_BUF
)
3281 bfd_putl32 (retval
- remaining
, r10_buf
);
3282 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3284 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3285 memcpy (cpu
->thread_data
[i
].cpu_context
,
3286 &cpu
->cpu_data_placeholder
,
3287 cpu
->thread_cpu_data_size
);
3288 memcpy (&cpu
->cpu_data_placeholder
,
3289 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3290 cpu
->thread_cpu_data_size
);
3291 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3292 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3299 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3302 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
3304 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
3310 /* Set target-specific callback data. */
3313 cris_set_callbacks (host_callback
*cb
)
3315 /* Yeargh, have to cast away constness to avoid warnings. */
3316 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3317 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3319 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3320 parameter to cb_store_target_endian will make st_size negative.
3321 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3322 *unsigned*, and/or add syntax for signed-ness. */
3323 cb
->stat_map
= stat_map
;
3324 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3325 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3326 cb
->pipe_empty
= cris_pipe_empty
;
3327 cb
->time
= cris_time
;
3330 /* Process an address exception. */
3333 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3334 unsigned int map
, int nr_bytes
, address_word addr
,
3335 transfer_type transfer
, sim_core_signals sig
)
3337 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,