1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Axis Communications.
6 This file is part of the GNU simulators.
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.
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.
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/>. */
22 #include "sim-options.h"
24 /* FIXME: get rid of targ-vals.h usage everywhere else. */
36 #ifdef HAVE_SYS_PARAM_H
37 #include <sys/param.h>
39 #ifdef HAVE_SYS_STAT_H
42 /* For PATH_MAX, originally. */
47 /* From ld/sysdep.h. */
49 # define SIM_PATHMAX PATH_MAX
52 # define SIM_PATHMAX MAXPATHLEN
54 # define SIM_PATHMAX 1024
58 /* The verbatim values are from asm-cris/unistd.h. */
60 #define TARGET_SYS_exit 1
61 #define TARGET_SYS_read 3
62 #define TARGET_SYS_write 4
63 #define TARGET_SYS_open 5
64 #define TARGET_SYS_close 6
65 #define TARGET_SYS_unlink 10
66 #define TARGET_SYS_time 13
67 #define TARGET_SYS_lseek 19
68 #define TARGET_SYS_getpid 20
69 #define TARGET_SYS_access 33
70 #define TARGET_SYS_kill 37
71 #define TARGET_SYS_rename 38
72 #define TARGET_SYS_pipe 42
73 #define TARGET_SYS_brk 45
74 #define TARGET_SYS_ioctl 54
75 #define TARGET_SYS_fcntl 55
76 #define TARGET_SYS_getppid 64
77 #define TARGET_SYS_setrlimit 75
78 #define TARGET_SYS_gettimeofday 78
79 #define TARGET_SYS_readlink 85
80 #define TARGET_SYS_munmap 91
81 #define TARGET_SYS_truncate 92
82 #define TARGET_SYS_ftruncate 93
83 #define TARGET_SYS_socketcall 102
84 #define TARGET_SYS_stat 106
85 #define TARGET_SYS_fstat 108
86 #define TARGET_SYS_wait4 114
87 #define TARGET_SYS_sigreturn 119
88 #define TARGET_SYS_clone 120
89 #define TARGET_SYS_uname 122
90 #define TARGET_SYS_mprotect 125
91 #define TARGET_SYS_llseek 140
92 #define TARGET_SYS_writev 146
93 #define TARGET_SYS__sysctl 149
94 #define TARGET_SYS_sched_setparam 154
95 #define TARGET_SYS_sched_getparam 155
96 #define TARGET_SYS_sched_setscheduler 156
97 #define TARGET_SYS_sched_getscheduler 157
98 #define TARGET_SYS_sched_yield 158
99 #define TARGET_SYS_sched_get_priority_max 159
100 #define TARGET_SYS_sched_get_priority_min 160
101 #define TARGET_SYS_mremap 163
102 #define TARGET_SYS_poll 168
103 #define TARGET_SYS_rt_sigaction 174
104 #define TARGET_SYS_rt_sigprocmask 175
105 #define TARGET_SYS_rt_sigsuspend 179
106 #define TARGET_SYS_getcwd 183
107 #define TARGET_SYS_ugetrlimit 191
108 #define TARGET_SYS_mmap2 192
109 #define TARGET_SYS_stat64 195
110 #define TARGET_SYS_lstat64 196
111 #define TARGET_SYS_fstat64 197
112 #define TARGET_SYS_geteuid32 201
113 #define TARGET_SYS_getuid32 199
114 #define TARGET_SYS_getegid32 202
115 #define TARGET_SYS_getgid32 200
116 #define TARGET_SYS_fcntl64 221
117 #define TARGET_SYS_set_thread_area 243
118 #define TARGET_SYS_exit_group 252
120 #define TARGET_PROT_READ 0x1
121 #define TARGET_PROT_WRITE 0x2
122 #define TARGET_PROT_EXEC 0x4
123 #define TARGET_PROT_NONE 0x0
125 #define TARGET_MAP_SHARED 0x01
126 #define TARGET_MAP_PRIVATE 0x02
127 #define TARGET_MAP_TYPE 0x0f
128 #define TARGET_MAP_FIXED 0x10
129 #define TARGET_MAP_ANONYMOUS 0x20
130 #define TARGET_MAP_DENYWRITE 0x800
132 #define TARGET_CTL_KERN 1
133 #define TARGET_CTL_VM 2
134 #define TARGET_CTL_NET 3
135 #define TARGET_CTL_PROC 4
136 #define TARGET_CTL_FS 5
137 #define TARGET_CTL_DEBUG 6
138 #define TARGET_CTL_DEV 7
139 #define TARGET_CTL_BUS 8
140 #define TARGET_CTL_ABI 9
142 #define TARGET_CTL_KERN_VERSION 4
145 #define TARGET_MREMAP_MAYMOVE 1
146 #define TARGET_MREMAP_FIXED 2
148 #define TARGET_TCGETS 0x5401
150 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
152 /* Seconds since 1970-01-01 to the above date + 10 minutes;
153 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
154 #define TARGET_EPOCH 1230764410
156 /* Milliseconds since start of run. We use the number of syscalls to
157 avoid introducing noise in the execution time. */
158 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
160 /* Seconds as in time(2). */
161 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
163 #define TARGET_SCHED_OTHER 0
165 #define TARGET_RLIMIT_STACK 3
166 #define TARGET_RLIMIT_NOFILE 7
168 #define SIM_TARGET_MAX_THREADS 64
169 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
171 /* From linux/sched.h. */
172 #define TARGET_CSIGNAL 0x000000ff
173 #define TARGET_CLONE_VM 0x00000100
174 #define TARGET_CLONE_FS 0x00000200
175 #define TARGET_CLONE_FILES 0x00000400
176 #define TARGET_CLONE_SIGHAND 0x00000800
177 #define TARGET_CLONE_PID 0x00001000
178 #define TARGET_CLONE_PTRACE 0x00002000
179 #define TARGET_CLONE_VFORK 0x00004000
180 #define TARGET_CLONE_PARENT 0x00008000
181 #define TARGET_CLONE_THREAD 0x00010000
182 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
184 /* From asm-cris/poll.h. */
185 #define TARGET_POLLIN 1
187 /* From asm-cris/signal.h. */
188 #define TARGET_SIG_BLOCK 0
189 #define TARGET_SIG_UNBLOCK 1
190 #define TARGET_SIG_SETMASK 2
192 #define TARGET_SIG_DFL 0
193 #define TARGET_SIG_IGN 1
194 #define TARGET_SIG_ERR ((USI)-1)
196 #define TARGET_SIGHUP 1
197 #define TARGET_SIGINT 2
198 #define TARGET_SIGQUIT 3
199 #define TARGET_SIGILL 4
200 #define TARGET_SIGTRAP 5
201 #define TARGET_SIGABRT 6
202 #define TARGET_SIGIOT 6
203 #define TARGET_SIGBUS 7
204 #define TARGET_SIGFPE 8
205 #define TARGET_SIGKILL 9
206 #define TARGET_SIGUSR1 10
207 #define TARGET_SIGSEGV 11
208 #define TARGET_SIGUSR2 12
209 #define TARGET_SIGPIPE 13
210 #define TARGET_SIGALRM 14
211 #define TARGET_SIGTERM 15
212 #define TARGET_SIGSTKFLT 16
213 #define TARGET_SIGCHLD 17
214 #define TARGET_SIGCONT 18
215 #define TARGET_SIGSTOP 19
216 #define TARGET_SIGTSTP 20
217 #define TARGET_SIGTTIN 21
218 #define TARGET_SIGTTOU 22
219 #define TARGET_SIGURG 23
220 #define TARGET_SIGXCPU 24
221 #define TARGET_SIGXFSZ 25
222 #define TARGET_SIGVTALRM 26
223 #define TARGET_SIGPROF 27
224 #define TARGET_SIGWINCH 28
225 #define TARGET_SIGIO 29
226 #define TARGET_SIGPOLL SIGIO
227 /* Actually commented out in the kernel header. */
228 #define TARGET_SIGLOST 29
229 #define TARGET_SIGPWR 30
230 #define TARGET_SIGSYS 31
232 /* From include/asm-cris/signal.h. */
233 #define TARGET_SA_NOCLDSTOP 0x00000001
234 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
235 #define TARGET_SA_SIGINFO 0x00000004
236 #define TARGET_SA_ONSTACK 0x08000000
237 #define TARGET_SA_RESTART 0x10000000
238 #define TARGET_SA_NODEFER 0x40000000
239 #define TARGET_SA_RESETHAND 0x80000000
240 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
241 #define TARGET_SA_RESTORER 0x04000000
243 /* From linux/wait.h. */
244 #define TARGET_WNOHANG 1
245 #define TARGET_WUNTRACED 2
246 #define TARGET___WNOTHREAD 0x20000000
247 #define TARGET___WALL 0x40000000
248 #define TARGET___WCLONE 0x80000000
250 /* From linux/limits.h. */
251 #define TARGET_PIPE_BUF 4096
254 #define TARGET_R_OK 4
255 #define TARGET_W_OK 2
256 #define TARGET_X_OK 1
257 #define TARGET_F_OK 0
259 static const char stat_map
[] =
260 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
261 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
262 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
265 static const CB_TARGET_DEFS_MAP syscall_map
[] =
267 { CB_SYS_open
, TARGET_SYS_open
},
268 { CB_SYS_close
, TARGET_SYS_close
},
269 { CB_SYS_read
, TARGET_SYS_read
},
270 { CB_SYS_write
, TARGET_SYS_write
},
271 { CB_SYS_lseek
, TARGET_SYS_lseek
},
272 { CB_SYS_unlink
, TARGET_SYS_unlink
},
273 { CB_SYS_getpid
, TARGET_SYS_getpid
},
274 { CB_SYS_fstat
, TARGET_SYS_fstat64
},
275 { CB_SYS_lstat
, TARGET_SYS_lstat64
},
276 { CB_SYS_stat
, TARGET_SYS_stat64
},
277 { CB_SYS_pipe
, TARGET_SYS_pipe
},
278 { CB_SYS_rename
, TARGET_SYS_rename
},
279 { CB_SYS_truncate
, TARGET_SYS_truncate
},
280 { CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
284 /* An older, 32-bit-only stat mapping. */
285 static const char stat32_map
[] =
286 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
287 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
288 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
290 /* Map for calls using the 32-bit struct stat. Primarily used by the
291 newlib Linux mapping. */
292 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
294 { CB_SYS_fstat
, TARGET_SYS_fstat
},
295 { CB_SYS_stat
, TARGET_SYS_stat
},
299 /* Giving the true value for the running sim process will lead to
300 non-time-invariant behavior. */
301 #define TARGET_PID 42
303 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
304 we did, we'd still don't get a register number with the "16" offset. */
305 #define TARGET_SRP_REGNUM (16+11)
307 /* Extracted by applying
308 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
309 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
310 adjusting the synonyms. */
312 static const CB_TARGET_DEFS_MAP errno_map
[] =
420 { ENAMETOOLONG
, 36 },
579 { EDESTADDRREQ
, 89 },
590 #ifdef EPROTONOSUPPORT
591 { EPROTONOSUPPORT
, 93 },
593 #ifdef ESOCKTNOSUPPORT
594 { ESOCKTNOSUPPORT
, 94 },
600 { EPFNOSUPPORT
, 96 },
603 { EAFNOSUPPORT
, 97 },
609 { EADDRNOTAVAIL
, 99 },
615 { ENETUNREACH
, 101 },
621 { ECONNABORTED
, 103 },
639 { ETOOMANYREFS
, 109 },
645 { ECONNREFUSED
, 111 },
651 { EHOSTUNREACH
, 113 },
657 { EINPROGRESS
, 115 },
684 { EMEDIUMTYPE
, 124 },
689 /* Extracted by applying
690 perl -ne 'if ($_ =~ /^#define/) { split;
691 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
692 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
693 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
694 installation and removing synonyms and unnecessary items. Don't
695 forget the end-marker. */
697 /* These we treat specially, as they're used in the fcntl F_GETFL
698 syscall. For consistency, open_map is also manually edited to use
700 #define TARGET_O_ACCMODE 0x3
701 #define TARGET_O_RDONLY 0x0
702 #define TARGET_O_WRONLY 0x1
704 static const CB_TARGET_DEFS_MAP open_map
[] = {
706 { O_ACCMODE
, TARGET_O_ACCMODE
},
709 { O_RDONLY
, TARGET_O_RDONLY
},
712 { O_WRONLY
, TARGET_O_WRONLY
},
733 { O_NONBLOCK
, 0x800 },
745 { O_DIRECT
, 0x4000 },
748 { O_LARGEFILE
, 0x8000 },
751 { O_DIRECTORY
, 0x10000 },
754 { O_NOFOLLOW
, 0x20000 },
759 /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
761 sim_io_error (sd, "simulator unhandled condition at %s:%d", \
762 __FUNCTION__, __LINE__)
764 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
765 static SIM_CPU
*current_cpu_for_cb_callback
;
767 static int syscall_read_mem (host_callback
*, struct cb_syscall
*,
768 unsigned long, char *, int);
769 static int syscall_write_mem (host_callback
*, struct cb_syscall
*,
770 unsigned long, const char *, int);
771 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
773 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
775 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
777 static void dump_statistics (SIM_CPU
*current_cpu
);
778 static void make_first_thread (SIM_CPU
*current_cpu
);
780 /* Read/write functions for system call interface. */
783 syscall_read_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
784 struct cb_syscall
*sc
,
785 unsigned long taddr
, char *buf
, int bytes
)
787 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
788 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
790 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
794 syscall_write_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
795 struct cb_syscall
*sc
,
796 unsigned long taddr
, const char *buf
, int bytes
)
798 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
799 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
801 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
804 /* When we risk running self-modified code (as in trampolines), this is
805 called from special-case insns. The silicon CRIS CPU:s have enough
806 cache snooping implemented making this a simulator-only issue. Tests:
807 gcc.c-torture/execute/931002-1.c execution, -O3 -g
808 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
811 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
812 USI pc ATTRIBUTE_UNUSED
)
814 SIM_DESC sd
= CPU_STATE (current_cpu
);
817 if (USING_SCACHE_P (sd
))
818 scache_flush_cpu (current_cpu
);
822 /* Output statistics at the end of a run. */
824 dump_statistics (SIM_CPU
*current_cpu
)
826 SIM_DESC sd
= CPU_STATE (current_cpu
);
827 CRIS_MISC_PROFILE
*profp
828 = CPU_CRIS_MISC_PROFILE (current_cpu
);
829 unsigned64 total
= profp
->basic_cycle_count
;
830 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
832 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
833 what's included in the "total" count only. */
834 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
835 & FLAG_CRIS_MISC_PROFILE_ALL
)
837 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
840 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
842 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
843 total
+= profp
->unaligned_mem_dword_count
;
846 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
847 textmsg
= "Schedulable clock cycles, total @: %llu\n";
849 += (profp
->memsrc_stall_count
850 + profp
->memraw_stall_count
851 + profp
->movemsrc_stall_count
852 + profp
->movemdst_stall_count
853 + profp
->mulsrc_stall_count
854 + profp
->jumpsrc_stall_count
855 + profp
->unaligned_mem_dword_count
);
858 case FLAG_CRIS_MISC_PROFILE_ALL
:
859 textmsg
= "All accounted clock cycles, total @: %llu\n";
861 += (profp
->memsrc_stall_count
862 + profp
->memraw_stall_count
863 + profp
->movemsrc_stall_count
864 + profp
->movemdst_stall_count
865 + profp
->movemaddr_stall_count
866 + profp
->mulsrc_stall_count
867 + profp
->jumpsrc_stall_count
868 + profp
->branch_stall_count
869 + profp
->jumptarget_stall_count
870 + profp
->unaligned_mem_dword_count
);
877 "Internal inconsistency at %s:%d",
879 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
880 sim_stopped
, SIM_SIGILL
);
883 /* Historically, these messages have gone to stderr, so we'll keep it
884 that way. It's also easier to then tell it from normal program
885 output. FIXME: Add redirect option like "run -e file". */
886 sim_io_eprintf (sd
, textmsg
, total
);
888 /* For v32, unaligned_mem_dword_count should always be 0. For
889 v10, memsrc_stall_count should always be 0. */
890 sim_io_eprintf (sd
, "Memory source stall cycles: %llu\n",
891 (unsigned long long) (profp
->memsrc_stall_count
892 + profp
->unaligned_mem_dword_count
));
893 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %llu\n",
894 (unsigned long long) profp
->memraw_stall_count
);
895 sim_io_eprintf (sd
, "Movem source stall cycles: %llu\n",
896 (unsigned long long) profp
->movemsrc_stall_count
);
897 sim_io_eprintf (sd
, "Movem destination stall cycles: %llu\n",
898 (unsigned long long) profp
->movemdst_stall_count
);
899 sim_io_eprintf (sd
, "Movem address stall cycles: %llu\n",
900 (unsigned long long) profp
->movemaddr_stall_count
);
901 sim_io_eprintf (sd
, "Multiplication source stall cycles: %llu\n",
902 (unsigned long long) profp
->mulsrc_stall_count
);
903 sim_io_eprintf (sd
, "Jump source stall cycles: %llu\n",
904 (unsigned long long) profp
->jumpsrc_stall_count
);
905 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %llu\n",
906 (unsigned long long) profp
->branch_stall_count
);
907 sim_io_eprintf (sd
, "Jump target stall cycles: %llu\n",
908 (unsigned long long) profp
->jumptarget_stall_count
);
911 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
912 Return 1 if a overlap detected, 0 otherwise. */
915 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
916 struct cris_sim_mmapped_page
**rootp
,
919 struct cris_sim_mmapped_page
*mapp
;
921 if (len
== 0 || (len
& 8191))
924 /* Iterate over the reverse-address sorted pages until we find a page in
925 or lower than the checked area. */
926 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
927 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
933 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
934 Return 1 if the whole area is mapped, 0 otherwise. */
937 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
938 struct cris_sim_mmapped_page
**rootp
,
941 struct cris_sim_mmapped_page
*mapp
;
943 if (len
== 0 || (len
& 8191))
946 /* Iterate over the reverse-address sorted pages until we find a page
947 lower than the checked area. */
948 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
949 if (addr
== mapp
->addr
&& len
== 8192)
951 else if (addr
+ len
> mapp
->addr
)
957 /* Debug helper; to be run from gdb. */
960 cris_dump_map (SIM_CPU
*current_cpu
)
962 struct cris_sim_mmapped_page
*mapp
;
965 for (mapp
= current_cpu
->highest_mmapped_page
,
966 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
967 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
971 if (mapp
->addr
!= start
- 8192)
973 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
974 end
= mapp
->addr
+ 8191;
980 if (current_cpu
->highest_mmapped_page
!= NULL
)
981 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
984 /* Create mmapped memory. ADDR is -1 if any address will do. Caller
985 must make sure that the address isn't already mapped. */
988 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
991 struct cris_sim_mmapped_page
*mapp
;
992 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
993 USI new_addr
= 0x40000000;
995 if (addr
!= (USI
) -1)
997 else if (*rootp
&& rootp
[0]->addr
>= new_addr
)
998 new_addr
= rootp
[0]->addr
+ 8192;
1005 /* Which is better: return an error for this, or just round it up? */
1008 /* Do a recursive call for each page in the request. */
1009 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
1010 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
1017 mapp
!= NULL
&& mapp
->addr
> new_addr
;
1019 higher_prevp
= &mapp
->prev
;
1021 /* Assert for consistency that we don't create duplicate maps. */
1022 if (is_mapped (sd
, rootp
, new_addr
, len
))
1025 /* Allocate the new page, on the next higher page from the last one
1026 allocated, and link in the new descriptor before previous ones. */
1027 mapp
= malloc (sizeof (*mapp
));
1030 return (USI
) -ENOMEM
;
1032 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1036 mapp
->addr
= new_addr
;
1037 mapp
->prev
= *higher_prevp
;
1038 *higher_prevp
= mapp
;
1043 /* Unmap one or more pages. */
1046 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1049 struct cris_sim_mmapped_page
*mapp
;
1050 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1058 /* Which is better: return an error for this, or just round it up? */
1061 /* Loop backwards to make each call is O(1) over the number of pages
1062 allocated, if we're unmapping from the high end of the pages. */
1063 for (page_addr
= addr
+ len
- 8192;
1066 if (unmap_pages (sd
, rootp
, page_addr
, 8192))
1069 if (unmap_pages (sd
, rootp
, addr
, 8192))
1075 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1076 higher_prevp
= &mapp
->prev
;
1078 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1081 *higher_prevp
= mapp
->prev
;
1082 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1087 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1090 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1092 SIM_DESC sd
= CPU_STATE (current_cpu
);
1094 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1098 /* Handlers from the CGEN description that should not be called. */
1101 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1102 UINT srcreg ATTRIBUTE_UNUSED
,
1103 USI dstreg ATTRIBUTE_UNUSED
)
1105 SIM_DESC sd
= CPU_STATE (current_cpu
);
1110 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1111 UINT index ATTRIBUTE_UNUSED
,
1112 USI page ATTRIBUTE_UNUSED
,
1113 USI newval ATTRIBUTE_UNUSED
)
1115 SIM_DESC sd
= CPU_STATE (current_cpu
);
1120 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1121 UINT index ATTRIBUTE_UNUSED
,
1122 USI page ATTRIBUTE_UNUSED
)
1124 SIM_DESC sd
= CPU_STATE (current_cpu
);
1128 /* Swap one context for another. */
1131 schedule (SIM_CPU
*current_cpu
, int next
)
1133 /* Need to mark context-switches in the trace output. */
1134 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1135 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1136 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1139 /* Copy the current context (if there is one) to its slot. */
1140 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1141 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1142 ¤t_cpu
->cpu_data_placeholder
,
1143 current_cpu
->thread_cpu_data_size
);
1145 /* Copy the new context from its slot. */
1146 memcpy (¤t_cpu
->cpu_data_placeholder
,
1147 current_cpu
->thread_data
[next
].cpu_context
,
1148 current_cpu
->thread_cpu_data_size
);
1150 /* Update needed stuff to indicate the new context. */
1151 current_cpu
->threadno
= next
;
1153 /* Handle pending signals. */
1154 if (current_cpu
->thread_data
[next
].sigpending
1155 /* We don't run nested signal handlers. This means that pause(2)
1156 and sigsuspend(2) do not work in sighandlers, but that
1157 shouldn't be too hard a restriction. It also greatly
1158 simplifies the code. */
1159 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1163 /* See if there's really a pending, non-blocked handler. We don't
1164 queue signals, so just use the first one in ascending order. */
1165 for (sig
= 0; sig
< 64; sig
++)
1166 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1167 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1173 USI pc
= sim_pc_get (current_cpu
);
1175 /* It's simpler to save the CPU context inside the simulator
1176 than on the stack. */
1177 current_cpu
->thread_data
[next
].cpu_context_atsignal
1179 ->make_thread_cpu_data
) (current_cpu
,
1180 current_cpu
->thread_data
[next
]
1183 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1184 sp
= bfd_getl32 (regbuf
);
1186 /* Make sure we have an aligned stack. */
1189 /* Make room for the signal frame, aligned. FIXME: Check that
1190 the memory exists, map it in if absent. (BTW, should also
1191 implement on-access automatic stack allocation). */
1194 /* This isn't the same signal frame as the kernel uses, because
1195 we don't want to bother getting all registers on and off the
1198 /* First, we store the currently blocked signals. */
1200 for (i
= 0; i
< 32; i
++)
1202 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1203 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1205 for (i
= 0; i
< 31; i
++)
1207 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1208 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1210 /* Then, the actual instructions. This is CPU-specific, but we
1211 use instructions from the common subset for v10 and v32 which
1212 should be safe for the time being but could be parametrized
1214 /* MOVU.W [PC+],R9. */
1215 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1216 /* .WORD TARGET_SYS_sigreturn. */
1217 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1218 TARGET_SYS_sigreturn
);
1220 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1222 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1223 instruction. Still, it doesn't matter because v10 has no
1224 delay slot for BREAK so it will not be executed). */
1225 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1227 /* Modify registers to hold the right values for the sighandler
1228 context: updated stackpointer and return address pointing to
1229 the sigreturn stub. */
1230 bfd_putl32 (sp
, regbuf
);
1231 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1232 bfd_putl32 (sp
+ 8, regbuf
);
1233 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1236 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1238 /* Block this signal (for the duration of the sighandler). */
1239 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1241 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1242 bfd_putl32 (sig
, regbuf
);
1243 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1246 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1247 needed all this for, specifies a SA_SIGINFO call but treats it
1248 like an ordinary sighandler; only the signal number argument is
1249 inspected. To make future need to implement SA_SIGINFO
1250 correctly possible, we set the siginfo argument register to a
1251 magic (hopefully non-address) number. (NB: then, you should
1252 just need to pass the siginfo argument; it seems you probably
1253 don't need to implement the specific rt_sigreturn.) */
1254 bfd_putl32 (0xbad5161f, regbuf
);
1255 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1258 /* The third argument is unused and the kernel sets it to 0. */
1259 bfd_putl32 (0, regbuf
);
1260 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1265 /* No, there actually was no pending signal for this thread. Reset
1267 current_cpu
->thread_data
[next
].sigpending
= 0;
1271 /* Reschedule the simplest possible way until something else is absolutely
1273 - A. Find the next process (round-robin) that doesn't have at_syscall
1275 - B. If there is none, just run the next process, round-robin.
1276 - Clear at_syscall for the current process. */
1279 reschedule (SIM_CPU
*current_cpu
)
1281 SIM_DESC sd
= CPU_STATE (current_cpu
);
1284 /* Iterate over all thread slots, because after a few thread creations
1285 and exits, we don't know where the live ones are. */
1286 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1287 i
!= current_cpu
->threadno
;
1288 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1289 if (current_cpu
->thread_data
[i
].cpu_context
1290 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1292 schedule (current_cpu
, i
);
1296 /* Pick any next live thread. */
1297 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1298 i
!= current_cpu
->threadno
;
1299 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1300 if (current_cpu
->thread_data
[i
].cpu_context
)
1302 schedule (current_cpu
, i
);
1306 /* More than one live thread, but we couldn't find the next one? */
1310 /* Set up everything to receive (or IGN) an incoming signal to the
1314 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1317 USI pc
= sim_pc_get (current_cpu
);
1319 /* Find the thread index of the pid. */
1320 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1321 /* Apparently it's ok to send signals to zombies (so a check for
1322 current_cpu->thread_data[i].cpu_context != NULL would be
1324 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1327 switch (current_cpu
->sighandler
[sig
])
1329 case TARGET_SIG_DFL
:
1332 /* The following according to the glibc
1333 documentation. (The kernel code has non-obvious
1334 execution paths.) */
1337 case TARGET_SIGSEGV
:
1339 case TARGET_SIGABRT
:
1340 case TARGET_SIGTRAP
:
1343 case TARGET_SIGTERM
:
1345 case TARGET_SIGQUIT
:
1346 case TARGET_SIGKILL
:
1349 case TARGET_SIGALRM
:
1350 case TARGET_SIGVTALRM
:
1351 case TARGET_SIGPROF
:
1352 case TARGET_SIGSTOP
:
1354 case TARGET_SIGPIPE
:
1355 case TARGET_SIGLOST
:
1356 case TARGET_SIGXCPU
:
1357 case TARGET_SIGXFSZ
:
1358 case TARGET_SIGUSR1
:
1359 case TARGET_SIGUSR2
:
1360 sim_io_eprintf (CPU_STATE (current_cpu
),
1361 "Exiting pid %d due to signal %d\n",
1363 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1364 NULL
, pc
, sim_stopped
,
1365 sig
== TARGET_SIGABRT
1366 ? SIM_SIGABRT
: SIM_SIGILL
);
1369 /* The default for all other signals is to be ignored. */
1374 case TARGET_SIG_IGN
:
1377 case TARGET_SIGKILL
:
1378 case TARGET_SIGSTOP
:
1379 /* Can't ignore these signals. */
1380 sim_io_eprintf (CPU_STATE (current_cpu
),
1381 "Exiting pid %d due to signal %d\n",
1383 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1384 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1393 /* Mark the signal as pending, making schedule () check
1394 closer. The signal will be handled when the thread is
1395 scheduled and the signal is unblocked. */
1396 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1397 current_cpu
->thread_data
[i
].sigpending
= 1;
1402 sim_io_eprintf (CPU_STATE (current_cpu
),
1403 "Unimplemented signal: %d\n", sig
);
1404 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1405 sim_stopped
, SIM_SIGILL
);
1410 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1414 /* Make the vector and the first item, the main thread. */
1417 make_first_thread (SIM_CPU
*current_cpu
)
1419 SIM_DESC sd
= CPU_STATE (current_cpu
);
1420 current_cpu
->thread_data
1422 SIM_TARGET_MAX_THREADS
1423 * sizeof (current_cpu
->thread_data
[0]));
1424 current_cpu
->thread_data
[0].cpu_context
1425 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1427 ->cpu_data_placeholder
);
1428 current_cpu
->thread_data
[0].parent_threadid
= -1;
1430 /* For good measure. */
1431 if (TARGET_SIG_DFL
!= 0)
1435 /* Handle unknown system calls. Returns (if it does) the syscall
1439 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1441 SIM_DESC sd
= CPU_STATE (current_cpu
);
1442 host_callback
*cb
= STATE_CALLBACK (sd
);
1444 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1445 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1450 sim_io_evprintf (sd
, s
, ap
);
1453 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1454 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1457 return -cb_host_to_target_errno (cb
, ENOSYS
);
1460 /* Main function: the handler of the "break 13" syscall insn. */
1463 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1464 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1468 SIM_DESC sd
= CPU_STATE (current_cpu
);
1469 host_callback
*cb
= STATE_CALLBACK (sd
);
1471 int threadno
= current_cpu
->threadno
;
1473 current_cpu
->syscalls
++;
1475 CB_SYSCALL_INIT (&s
);
1481 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1482 to sign-extend the lseek offset to be passed as a signed number,
1483 else we'll truncate it to something > 2GB on hosts where sizeof
1484 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
1485 e.g. an address for some syscalls. */
1486 if (callnum
== TARGET_SYS_lseek
)
1489 if (callnum
== TARGET_SYS_exit_group
1490 || (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0))
1492 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1493 & FLAG_CRIS_MISC_PROFILE_ALL
)
1494 dump_statistics (current_cpu
);
1495 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1499 s
.p2
= (PTR
) current_cpu
;
1500 s
.read_mem
= syscall_read_mem
;
1501 s
.write_mem
= syscall_write_mem
;
1503 current_cpu_for_cb_callback
= current_cpu
;
1505 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1508 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1510 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1513 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1515 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1517 /* If the generic simulator call said ENOSYS, then let's try the
1518 ones we know ourselves.
1520 The convention is to provide *very limited* functionality on an
1521 as-needed basis, only what's covered by the test-suite, tests
1522 added when functionality changes and abort with a descriptive
1523 message for *everything* else. Where there's no test-case, we
1528 /* It's a pretty safe bet that the "old setup() system call"
1529 number will not be re-used; we can't say the same for higher
1530 numbers. We treat this simulator-generated call as "wait
1531 forever"; we re-run this insn. The wait is ended by a
1532 callback. Sanity check that this is the reason we got
1534 if (current_cpu
->thread_data
== NULL
1535 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1536 goto unimplemented_syscall
;
1538 sim_pc_set (current_cpu
, pc
);
1542 case TARGET_SYS_fcntl64
:
1543 case TARGET_SYS_fcntl
:
1548 Glibc checks stdin, stdout and stderr fd:s for
1549 close-on-exec security sanity. We just need to provide a
1550 OK return value. If we really need to have a
1551 close-on-exec flag true, we could just do a real fcntl
1557 /* F_SETFD. Just ignore attempts to set the close-on-exec
1563 /* F_GETFL. Check for the special case for open+fdopen. */
1564 if (current_cpu
->last_syscall
== TARGET_SYS_open
1565 && arg1
== current_cpu
->last_open_fd
)
1567 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1572 /* Because we can't freopen fd:s 0, 1, 2 to mean
1573 something else than stdin, stdout and stderr
1574 (sim/common/syscall.c:cb_syscall special cases fd
1575 0, 1 and 2), we know what flags that we can
1576 sanely return for these fd:s. */
1577 retval
= TARGET_O_RDONLY
;
1580 else if (arg1
== 1 || arg1
== 2)
1582 retval
= TARGET_O_WRONLY
;
1587 /* Nothing else is implemented. */
1589 = cris_unknown_syscall (current_cpu
, pc
,
1590 "Unimplemented %s syscall "
1591 "(fd: 0x%lx: cmd: 0x%lx arg: "
1593 callnum
== TARGET_SYS_fcntl
1594 ? "fcntl" : "fcntl64",
1595 (unsigned long) (USI
) arg1
,
1596 (unsigned long) (USI
) arg2
,
1597 (unsigned long) (USI
) arg3
);
1602 case TARGET_SYS_uname
:
1604 /* Fill in a few constants to appease glibc. */
1605 static char sim_utsname
[6][65] =
1611 "cris", /* Overwritten below. */
1615 /* Having the hardware type in Linux equal to the bfd
1616 printable name is deliberate: if you make config.guess
1617 work on your Linux-type system the usual way, it
1618 probably will; either the bfd printable_name or the
1619 ambiguous arch_name. */
1620 strcpy (sim_utsname
[4], STATE_ARCHITECTURE (sd
)->printable_name
);
1622 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1623 sizeof (sim_utsname
))
1624 != sizeof (sim_utsname
))
1625 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1631 case TARGET_SYS_geteuid32
:
1632 /* We tell the truth with these. Maybe we shouldn't, but it
1633 should match the "stat" information. */
1634 retval
= geteuid ();
1637 case TARGET_SYS_getuid32
:
1641 case TARGET_SYS_getegid32
:
1642 retval
= getegid ();
1645 case TARGET_SYS_getgid32
:
1649 case TARGET_SYS_brk
:
1650 /* Most often, we just return the argument, like the Linux
1655 retval
= current_cpu
->endbrk
;
1656 else if (arg1
<= current_cpu
->endmem
)
1657 current_cpu
->endbrk
= arg1
;
1660 USI new_end
= (arg1
+ 8191) & ~8191;
1662 /* If the simulator wants to brk more than a certain very
1663 large amount, something is wrong. FIXME: Return an error
1664 or abort? Have command-line selectable? */
1665 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1667 current_cpu
->endbrk
= current_cpu
->endmem
;
1668 retval
= current_cpu
->endmem
;
1672 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1673 current_cpu
->endmem
,
1674 new_end
- current_cpu
->endmem
,
1676 current_cpu
->endbrk
= arg1
;
1677 current_cpu
->endmem
= new_end
;
1681 case TARGET_SYS_getpid
:
1682 /* Correct until CLONE_THREAD is implemented. */
1683 retval
= current_cpu
->thread_data
== NULL
1685 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1688 case TARGET_SYS_getppid
:
1689 /* Correct until CLONE_THREAD is implemented. */
1690 retval
= current_cpu
->thread_data
== NULL
1693 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1696 case TARGET_SYS_mmap2
:
1705 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1706 still masked away this bit, so let's just ignore
1708 flags
&= ~TARGET_MAP_DENYWRITE
;
1710 /* If the simulator wants to mmap more than the very large
1711 limit, something is wrong. FIXME: Return an error or
1712 abort? Have command-line selectable? */
1713 if (len
> SIM_MAX_ALLOC_CHUNK
)
1715 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1719 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1721 != (TARGET_PROT_READ
1723 | TARGET_PROT_EXEC
))
1724 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1725 && prot
!= TARGET_PROT_READ
)
1726 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1727 && flags
!= TARGET_MAP_PRIVATE
1728 && flags
!= (TARGET_MAP_ANONYMOUS
1729 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1730 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1731 && flags
!= TARGET_MAP_SHARED
)
1733 && prot
!= TARGET_PROT_READ
1734 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1735 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1736 || (fd
== (USI
) -1 && pgoff
!= 0)
1737 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
)))
1740 = cris_unknown_syscall (current_cpu
, pc
,
1741 "Unimplemented mmap2 call "
1742 "(0x%lx, 0x%lx, 0x%lx, "
1743 "0x%lx, 0x%lx, 0x%lx)\n",
1744 (unsigned long) arg1
,
1745 (unsigned long) arg2
,
1746 (unsigned long) arg3
,
1747 (unsigned long) arg4
,
1748 (unsigned long) arg5
,
1749 (unsigned long) arg6
);
1752 else if (fd
!= (USI
) -1)
1759 /* A non-aligned argument is allowed for files. */
1760 USI newlen
= (len
+ 8191) & ~8191;
1762 /* We only support read, read|exec, and read|write,
1763 which we should already have checked. Check again
1765 if (prot
!= TARGET_PROT_READ
1766 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1767 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1770 if (flags
& TARGET_MAP_FIXED
)
1771 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1773 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1778 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1779 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1783 if (newaddr
>= (USI
) -8191)
1786 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1790 /* We were asked for MAP_FIXED, but couldn't. */
1791 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1794 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1796 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1800 /* Find the current position in the file. */
1801 s
.func
= TARGET_SYS_lseek
;
1805 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1812 /* Move to the correct offset in the file. */
1813 s
.func
= TARGET_SYS_lseek
;
1815 s
.arg2
= pgoff
*8192;
1817 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1823 /* Use the standard read callback to read in "len"
1825 s
.func
= TARGET_SYS_read
;
1829 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1832 /* If the result is a page or more lesser than what
1833 was requested, something went wrong. */
1834 if (len
>= 8192 && (USI
) s
.result
<= len
- 8192)
1837 /* After reading, we need to go back to the previous
1838 position in the file. */
1839 s
.func
= TARGET_SYS_lseek
;
1843 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1845 if (pos
!= (USI
) s
.result
)
1852 USI newlen
= (len
+ 8191) & ~8191;
1855 if (flags
& TARGET_MAP_FIXED
)
1856 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1858 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1862 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1863 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1867 if (newaddr
>= (USI
) -8191)
1868 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1872 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1875 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1877 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1884 case TARGET_SYS_mprotect
:
1886 /* We only cover the case of linuxthreads mprotecting out
1887 its stack guard page and of dynamic loading mprotecting
1888 away the data (for some reason the whole library, then
1889 mprotects away the data part and mmap-FIX:es it again. */
1894 if (prot
!= TARGET_PROT_NONE
1895 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1896 addr
, (len
+ 8191) & ~8191))
1899 = cris_unknown_syscall (current_cpu
, pc
,
1900 "Unimplemented mprotect call "
1901 "(0x%lx, 0x%lx, 0x%lx)\n",
1902 (unsigned long) arg1
,
1903 (unsigned long) arg2
,
1904 (unsigned long) arg3
);
1908 /* Just ignore this. We could make this equal to munmap,
1909 but then we'd have to make sure no anon mmaps gets this
1910 address before a subsequent MAP_FIXED mmap intended to
1916 case TARGET_SYS_ioctl
:
1918 /* We support only a very limited functionality: checking
1919 stdout with TCGETS to perform the isatty function. The
1920 TCGETS ioctl isn't actually performed or the result used by
1921 an isatty () caller in a "hello, world" program; only the
1922 return value is then used. Maybe we shouldn't care about
1923 the environment of the simulator regarding isatty, but
1924 that's been working before, in the xsim simulator. */
1925 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1926 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1928 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1932 case TARGET_SYS_munmap
:
1937 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1939 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1943 case TARGET_SYS_wait4
:
1951 /* FIXME: We're not properly implementing __WCLONE, and we
1952 don't really need the special casing so we might as well
1953 make this general. */
1954 if ((!(pid
== (USI
) -1
1955 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1958 && (options
== TARGET___WCLONE
1959 || options
== TARGET___WALL
)))
1961 || current_cpu
->thread_data
== NULL
)
1964 = cris_unknown_syscall (current_cpu
, pc
,
1965 "Unimplemented wait4 call "
1966 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1967 (unsigned long) arg1
,
1968 (unsigned long) arg2
,
1969 (unsigned long) arg3
,
1970 (unsigned long) arg4
);
1974 if (pid
== (USI
) -1)
1975 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1977 if (current_cpu
->thread_data
[threadno
].threadid
1978 == current_cpu
->thread_data
[i
].parent_threadid
1979 && current_cpu
->thread_data
[i
].threadid
!= 0
1980 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1982 /* A zombied child. Get the exit value and clear the
1983 zombied entry so it will be reused. */
1984 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1986 ->thread_data
[i
].exitval
);
1988 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1989 memset (¤t_cpu
->thread_data
[i
], 0,
1990 sizeof (current_cpu
->thread_data
[i
]));
1996 /* We're waiting for a specific PID. If we don't find
1997 it zombied on this run, rerun the syscall. */
1998 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1999 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
2000 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
2003 /* Get the exit value if the caller wants it. */
2004 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
2011 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
2012 memset (¤t_cpu
->thread_data
[i
], 0,
2013 sizeof (current_cpu
->thread_data
[i
]));
2018 sim_pc_set (current_cpu
, pc
);
2021 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
2026 case TARGET_SYS_rt_sigaction
:
2034 __sighandler_t sa_handler;
2035 unsigned long sa_flags;
2036 void (*sa_restorer)(void);
2042 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
2043 current_cpu
->sighandler
[signum
]);
2044 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
2045 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
2047 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2048 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
2049 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
2053 USI target_sa_handler
2054 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2056 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2057 USI target_sa_restorer
2058 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2059 USI target_sa_mask_low
2060 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2061 USI target_sa_mask_high
2062 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2064 /* We won't interrupt a syscall so we won't restart it,
2065 but a signal(2) call ends up syscalling rt_sigaction
2066 with this flag, so we have to handle it. The
2067 sa_restorer field contains garbage when not
2068 TARGET_SA_RESTORER, so don't look at it. For the
2069 time being, we don't nest sighandlers, so we
2070 ignore the sa_mask, which simplifies things. */
2071 if ((target_sa_flags
!= 0
2072 && target_sa_flags
!= TARGET_SA_RESTART
2073 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2074 || target_sa_handler
== 0)
2077 = cris_unknown_syscall (current_cpu
, pc
,
2078 "Unimplemented rt_sigaction "
2081 "[0x%x, 0x%x, 0x%x, "
2082 "{0x%x, 0x%x}], 0x%lx)\n",
2083 (unsigned long) arg1
,
2084 (unsigned long) arg2
,
2089 target_sa_mask_high
,
2090 (unsigned long) arg3
);
2094 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2096 /* Because we may have unblocked signals, one may now be
2097 pending, if there are threads, that is. */
2098 if (current_cpu
->thread_data
)
2099 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2105 case TARGET_SYS_mremap
:
2111 USI new_addr
= arg5
;
2114 if (new_len
== old_len
)
2115 /* The program and/or library is possibly confused but
2116 this is a valid call. Happens with ipps-1.40 on file
2119 else if (new_len
< old_len
)
2121 /* Shrinking is easy. */
2122 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2123 addr
+ new_len
, old_len
- new_len
) != 0)
2124 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2128 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2129 addr
+ old_len
, new_len
- old_len
))
2131 /* If the extension isn't mapped, we can just add it. */
2133 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2134 addr
+ old_len
, new_len
- old_len
);
2136 if (mapped_addr
> (USI
) -8192)
2137 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2141 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2143 /* Create a whole new map and copy the contents
2144 block-by-block there. We ignore the new_addr argument
2147 USI prev_addr
= addr
;
2148 USI prev_len
= old_len
;
2151 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2154 if (mapped_addr
> (USI
) -8192)
2156 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2160 retval
= mapped_addr
;
2163 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2165 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2167 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2168 mapped_addr
, 8192) != 8192)
2172 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2173 prev_addr
, prev_len
) != 0)
2177 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2181 case TARGET_SYS_poll
:
2183 int npollfds
= arg2
;
2199 /* Check that this is the expected poll call from
2200 linuxthreads/manager.c; we don't support anything else.
2201 Remember, fd == 0 isn't supported. */
2203 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2205 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2208 || ((cb
->fstat
) (cb
, fd
, &buf
) != 0
2209 || (buf
.st_mode
& S_IFIFO
) == 0)
2210 || current_cpu
->thread_data
== NULL
)
2213 = cris_unknown_syscall (current_cpu
, pc
,
2214 "Unimplemented poll syscall "
2215 "(0x%lx: [0x%x, 0x%x, x], "
2217 (unsigned long) arg1
, fd
, events
,
2218 (unsigned long) arg2
,
2219 (unsigned long) arg3
);
2225 /* Iterate over threads; find a marker that a writer is
2226 sleeping, waiting for a reader. */
2227 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2228 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2229 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2231 revents
= TARGET_POLLIN
;
2236 /* Timeout decreases with whatever time passed between the
2237 last syscall and this. That's not exactly right for the
2238 first call, but it's close enough that it isn't
2239 worthwhile to complicate matters by making that a special
2242 -= (TARGET_TIME_MS (current_cpu
)
2243 - (current_cpu
->thread_data
[threadno
].last_execution
));
2245 /* Arrange to repeat this syscall until timeout or event,
2246 decreasing timeout at each iteration. */
2247 if (timeout
> 0 && revents
== 0)
2249 bfd_byte timeout_buf
[4];
2251 bfd_putl32 (timeout
, timeout_buf
);
2252 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2253 H_GR_R12
, timeout_buf
, 4);
2254 sim_pc_set (current_cpu
, pc
);
2259 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2264 case TARGET_SYS_time
:
2266 retval
= (int) (*cb
->time
) (cb
, 0L);
2268 /* At time of this writing, CB_SYSCALL_time doesn't do the
2269 part of setting *arg1 to the return value. */
2271 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2275 case TARGET_SYS_gettimeofday
:
2278 USI ts
= TARGET_TIME (current_cpu
);
2279 USI tms
= TARGET_TIME_MS (current_cpu
);
2281 /* First dword is seconds since TARGET_EPOCH. */
2282 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2284 /* Second dword is microseconds. */
2285 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2286 (tms
% 1000) * 1000);
2290 /* Time-zone info is always cleared. */
2291 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2292 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2297 case TARGET_SYS_llseek
:
2299 /* If it fits, tweak parameters to fit the "generic" 32-bit
2300 lseek and use that. */
2308 if (!((offs_hi
== 0 && offs_lo
>= 0)
2309 || (offs_hi
== -1 && offs_lo
< 0)))
2312 = cris_unknown_syscall (current_cpu
, pc
,
2313 "Unimplemented llseek offset,"
2314 " fd %d: 0x%x:0x%x\n",
2315 fd
, (unsigned) arg2
,
2320 s
.func
= TARGET_SYS_lseek
;
2323 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2325 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2327 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2330 retval
= -s
.errcode
;
2333 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2335 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2336 s
.result
< 0 ? -1 : 0);
2341 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2344 void *iov_base; Starting address
2345 size_t iov_len; Number of bytes to transfer
2347 case TARGET_SYS_writev
:
2355 /* We'll ignore strict error-handling and just do multiple write calls. */
2356 for (i
= 0; i
< iovcnt
; i
++)
2360 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2363 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2366 s
.func
= TARGET_SYS_write
;
2371 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2373 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2375 if (sysret
!= iov_len
)
2390 /* This one does have a generic callback function, but at the time
2391 of this writing, cb_syscall does not have code for it, and we
2392 need target-specific code for the threads implementation
2394 case TARGET_SYS_kill
:
2401 /* At kill(2), glibc sets signal masks such that the thread
2402 machinery is initialized. Still, there is and was only
2404 if (current_cpu
->max_threadid
== 0)
2406 if (pid
!= TARGET_PID
)
2408 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2412 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2413 if (sig
== TARGET_SIGABRT
)
2414 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2415 the end-point for failing GCC test-cases. */
2416 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2420 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2421 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2425 /* This will not be reached. */
2429 retval
= deliver_signal (current_cpu
, sig
, pid
);
2433 case TARGET_SYS_rt_sigprocmask
:
2440 if (how
!= TARGET_SIG_BLOCK
2441 && how
!= TARGET_SIG_SETMASK
2442 && how
!= TARGET_SIG_UNBLOCK
)
2445 = cris_unknown_syscall (current_cpu
, pc
,
2446 "Unimplemented rt_sigprocmask "
2447 "syscall (0x%x, 0x%x, 0x%x)\n",
2455 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2458 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2461 /* The sigmask is kept in the per-thread data, so we may
2462 need to create the first one. */
2463 if (current_cpu
->thread_data
== NULL
)
2464 make_first_thread (current_cpu
);
2466 if (how
== TARGET_SIG_SETMASK
)
2467 for (i
= 0; i
< 64; i
++)
2468 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2470 for (i
= 0; i
< 32; i
++)
2471 if ((set_low
& (1 << i
)))
2472 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2473 = (how
!= TARGET_SIG_UNBLOCK
);
2475 for (i
= 0; i
< 31; i
++)
2476 if ((set_high
& (1 << i
)))
2477 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2478 = (how
!= TARGET_SIG_UNBLOCK
);
2480 /* The mask changed, so a signal may be unblocked for
2482 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2490 for (i
= 0; i
< 32; i
++)
2491 if (current_cpu
->thread_data
[threadno
]
2492 .sigdata
[i
+ 1].blocked
)
2494 for (i
= 0; i
< 31; i
++)
2495 if (current_cpu
->thread_data
[threadno
]
2496 .sigdata
[i
+ 33].blocked
)
2499 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2500 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2507 case TARGET_SYS_sigreturn
:
2511 int was_sigsuspended
;
2513 if (current_cpu
->thread_data
== NULL
2514 /* The CPU context is saved with the simulator data, not
2515 on the stack as in the real world. */
2516 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2520 = cris_unknown_syscall (current_cpu
, pc
,
2521 "Invalid sigreturn syscall: "
2522 "no signal handler active "
2523 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2525 (unsigned long) arg1
,
2526 (unsigned long) arg2
,
2527 (unsigned long) arg3
,
2528 (unsigned long) arg4
,
2529 (unsigned long) arg5
,
2530 (unsigned long) arg6
);
2535 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2537 /* Restore the sigmask, either from the stack copy made when
2538 the sighandler was called, or from the saved state
2539 specifically for sigsuspend(2). */
2540 if (was_sigsuspended
)
2542 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2543 for (i
= 0; i
< 64; i
++)
2544 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2545 = current_cpu
->thread_data
[threadno
]
2546 .sigdata
[i
].blocked_suspendsave
;
2554 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2555 H_GR_SP
, regbuf
, 4);
2556 sp
= bfd_getl32 (regbuf
);
2558 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2560 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2562 for (i
= 0; i
< 32; i
++)
2563 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2564 = (set_low
& (1 << i
)) != 0;
2565 for (i
= 0; i
< 31; i
++)
2566 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2567 = (set_high
& (1 << i
)) != 0;
2570 /* The mask changed, so a signal may be unblocked for
2572 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2574 memcpy (¤t_cpu
->cpu_data_placeholder
,
2575 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2576 current_cpu
->thread_cpu_data_size
);
2577 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2578 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2580 /* The return value must come from the saved R10. */
2581 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2582 retval
= bfd_getl32 (regbuf
);
2584 /* We must also break the "sigsuspension loop". */
2585 if (was_sigsuspended
)
2586 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2590 case TARGET_SYS_rt_sigsuspend
:
2598 = cris_unknown_syscall (current_cpu
, pc
,
2599 "Unimplemented rt_sigsuspend syscall"
2600 " arguments (0x%lx, 0x%lx)\n",
2601 (unsigned long) arg1
,
2602 (unsigned long) arg2
);
2606 /* Don't change the signal mask if we're already in
2607 sigsuspend state (i.e. this syscall is a rerun). */
2608 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2611 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2614 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2618 /* Save the current sigmask and insert the user-supplied
2620 for (i
= 0; i
< 32; i
++)
2622 current_cpu
->thread_data
[threadno
]
2623 .sigdata
[i
+ 1].blocked_suspendsave
2624 = current_cpu
->thread_data
[threadno
]
2625 .sigdata
[i
+ 1].blocked
;
2627 current_cpu
->thread_data
[threadno
]
2628 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2630 for (i
= 0; i
< 31; i
++)
2632 current_cpu
->thread_data
[threadno
]
2633 .sigdata
[i
+ 33].blocked_suspendsave
2634 = current_cpu
->thread_data
[threadno
]
2635 .sigdata
[i
+ 33].blocked
;
2636 current_cpu
->thread_data
[threadno
]
2637 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2640 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2642 /* The mask changed, so a signal may be unblocked for
2644 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2647 /* Because we don't use arg1 (newsetp) when this syscall is
2648 rerun, it doesn't matter that we overwrite it with the
2649 (constant) return value. */
2650 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2651 sim_pc_set (current_cpu
, pc
);
2655 /* Add case labels here for other syscalls using the 32-bit
2656 "struct stat", provided they have a corresponding simulator
2657 function of course. */
2658 case TARGET_SYS_stat
:
2659 case TARGET_SYS_fstat
:
2661 /* As long as the infrastructure doesn't cache anything
2662 related to the stat mapping, this trick gets us a dual
2663 "struct stat"-type mapping in the least error-prone way. */
2664 const char *saved_map
= cb
->stat_map
;
2665 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2667 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2668 cb
->stat_map
= stat32_map
;
2670 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2673 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2676 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2678 cb
->stat_map
= saved_map
;
2679 cb
->syscall_map
= saved_syscall_map
;
2683 case TARGET_SYS_getcwd
:
2688 char *cwd
= xmalloc (SIM_PATHMAX
);
2689 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2692 /* FIXME: When and if we support chdir, we need something
2693 a bit more elaborate. */
2694 if (simulator_sysroot
[0] != '\0')
2697 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2698 if (strlen (cwd
) + 1 <= size
)
2700 retval
= strlen (cwd
) + 1;
2701 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2703 != (unsigned int) retval
)
2704 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2710 case TARGET_SYS_access
:
2714 char *pbuf
= xmalloc (SIM_PATHMAX
);
2719 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2721 strcpy (pbuf
, simulator_sysroot
);
2722 o
+= strlen (simulator_sysroot
);
2725 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2728 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2729 if (pbuf
[i
+ o
] == 0)
2733 if (i
+ o
== SIM_PATHMAX
)
2735 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2739 /* Assert that we don't get calls for files for which we
2740 don't have support. */
2741 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2744 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2751 if (access (pbuf
, hmode
) != 0)
2752 retval
= -cb_host_to_target_errno (cb
, errno
);
2760 case TARGET_SYS_readlink
:
2765 char *pbuf
= xmalloc (SIM_PATHMAX
);
2766 char *lbuf
= xmalloc (SIM_PATHMAX
);
2767 char *lbuf_alloc
= lbuf
;
2772 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2774 strcpy (pbuf
, simulator_sysroot
);
2775 o
+= strlen (simulator_sysroot
);
2778 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2781 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2782 if (pbuf
[i
+ o
] == 0)
2786 if (i
+ o
== SIM_PATHMAX
)
2788 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2792 /* Intervene calls for certain files expected in the target
2793 proc file system. */
2794 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2795 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2798 = (STATE_PROG_ARGV (sd
) != NULL
2799 ? *STATE_PROG_ARGV (sd
) : NULL
);
2801 if (argv0
== NULL
|| *argv0
== '.')
2804 = cris_unknown_syscall (current_cpu
, pc
,
2805 "Unimplemented readlink syscall "
2806 "(0x%lx: [\"%s\"], 0x%lx)\n",
2807 (unsigned long) arg1
, pbuf
,
2808 (unsigned long) arg2
);
2811 else if (*argv0
== '/')
2813 if (strncmp (simulator_sysroot
, argv0
,
2814 strlen (simulator_sysroot
)) == 0)
2815 argv0
+= strlen (simulator_sysroot
);
2817 strcpy (lbuf
, argv0
);
2818 nchars
= strlen (argv0
) + 1;
2822 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2823 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2825 if (strncmp (simulator_sysroot
, lbuf
,
2826 strlen (simulator_sysroot
)) == 0)
2827 lbuf
+= strlen (simulator_sysroot
);
2830 strcat (lbuf
, argv0
);
2831 nchars
= strlen (lbuf
) + 1;
2838 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2840 /* We trust that the readlink result returns a *relative*
2841 link, or one already adjusted for the file-path-prefix.
2842 (We can't generally tell the difference, so we go with
2843 the easiest decision; no adjustment.) */
2847 retval
= -cb_host_to_target_errno (cb
, errno
);
2851 if (bufsiz
< nchars
)
2854 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2855 buf
, nchars
) != (unsigned int) nchars
)
2856 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2865 case TARGET_SYS_sched_getscheduler
:
2869 /* FIXME: Search (other) existing threads. */
2870 if (pid
!= 0 && pid
!= TARGET_PID
)
2871 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2873 retval
= TARGET_SCHED_OTHER
;
2877 case TARGET_SYS_sched_getparam
:
2883 struct sched_param {
2887 if (pid
!= 0 && pid
!= TARGET_PID
)
2888 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2891 /* FIXME: Save scheduler setting before threads are
2893 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2894 current_cpu
->thread_data
!= NULL
2896 ->thread_data
[threadno
]
2904 case TARGET_SYS_sched_setparam
:
2909 if ((pid
!= 0 && pid
!= TARGET_PID
)
2910 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2912 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2918 case TARGET_SYS_sched_setscheduler
:
2924 if ((pid
!= 0 && pid
!= TARGET_PID
)
2925 || policy
!= TARGET_SCHED_OTHER
2926 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2928 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2930 /* FIXME: Save scheduler setting to be read in later
2931 sched_getparam calls. */
2936 case TARGET_SYS_sched_yield
:
2937 /* We reschedule to the next thread after a syscall anyway, so
2938 we don't have to do anything here than to set the return
2943 case TARGET_SYS_sched_get_priority_min
:
2944 case TARGET_SYS_sched_get_priority_max
:
2946 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2951 case TARGET_SYS_ugetrlimit
:
2953 unsigned int curlim
, maxlim
;
2954 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2956 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2962 unsigned long rlim_cur;
2963 unsigned long rlim_max;
2965 if (arg1
== TARGET_RLIMIT_NOFILE
)
2967 /* Sadly a very low limit. Better not lie, though. */
2968 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2970 else /* arg1 == TARGET_RLIMIT_STACK */
2972 maxlim
= 0xffffffff;
2975 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2976 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2981 case TARGET_SYS_setrlimit
:
2982 if (arg1
!= TARGET_RLIMIT_STACK
)
2984 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2987 /* FIXME: Save values for future ugetrlimit calls. */
2991 /* Provide a very limited subset of the sysctl functions, and
2992 abort for the rest. */
2993 case TARGET_SYS__sysctl
:
2996 struct __sysctl_args {
3003 unsigned long __unused[4];
3005 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
3006 SI name0
= name
== 0
3007 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
3008 SI name1
= name
== 0
3009 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
3011 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
3013 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
3015 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
3016 SI oldlen
= oldlenp
== 0
3017 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
3019 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
3021 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
3023 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
3025 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
3026 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
3028 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
3029 sizeof (TARGET_UTSNAME
));
3031 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
3032 TARGET_UTSNAME
, oldval
,
3034 != (unsigned int) to_write
)
3035 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
3042 = cris_unknown_syscall (current_cpu
, pc
,
3043 "Unimplemented _sysctl syscall "
3044 "(0x%lx: [0x%lx, 0x%lx],"
3045 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3046 (unsigned long) name
,
3047 (unsigned long) name0
,
3048 (unsigned long) name1
,
3049 (unsigned long) nlen
,
3050 (unsigned long) oldval
,
3051 (unsigned long) oldlenp
,
3052 (unsigned long) newval
,
3053 (unsigned long) newlen
);
3057 case TARGET_SYS_exit
:
3059 /* Here for all but the last thread. */
3062 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3064 = (current_cpu
->thread_data
[threadno
].parent_threadid
3066 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3068 /* Any children are now all orphans. */
3069 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3070 if (current_cpu
->thread_data
[i
].parent_threadid
3071 == current_cpu
->thread_data
[threadno
].threadid
)
3072 /* Make getppid(2) return 1 for them, poor little ones. */
3073 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3075 /* Free the cpu context data. When the parent has received
3076 the exit status, we'll clear the entry too. */
3077 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3078 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3079 current_cpu
->m1threads
--;
3082 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3084 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3088 /* Still, we may want to support non-zero exit values. */
3089 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3092 deliver_signal (current_cpu
, exitsig
, ppid
);
3096 case TARGET_SYS_clone
:
3098 int nthreads
= current_cpu
->m1threads
+ 1;
3099 void *thread_cpu_data
;
3100 bfd_byte old_sp_buf
[4];
3102 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3105 /* That's right, the syscall clone arguments are reversed
3106 compared to sys_clone notes in clone(2) and compared to
3107 other Linux ports (i.e. it's the same order as in the
3108 clone(2) libcall). */
3112 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3114 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3118 /* FIXME: Implement the low byte. */
3119 if ((flags
& ~TARGET_CSIGNAL
) !=
3122 | TARGET_CLONE_FILES
3123 | TARGET_CLONE_SIGHAND
)
3127 = cris_unknown_syscall (current_cpu
, pc
,
3128 "Unimplemented clone syscall "
3130 (unsigned long) arg1
,
3131 (unsigned long) arg2
);
3135 if (current_cpu
->thread_data
== NULL
)
3136 make_first_thread (current_cpu
);
3138 /* The created thread will get the new SP and a cleared R10.
3139 Since it's created out of a copy of the old thread and we
3140 don't have a set-register-function that just take the
3141 cpu_data as a parameter, we set the childs values first,
3142 and write back or overwrite them in the parent after the
3144 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3145 H_GR_SP
, old_sp_buf
, 4);
3146 bfd_putl32 (newsp
, sp_buf
);
3147 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3148 H_GR_SP
, sp_buf
, 4);
3149 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3150 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3153 ->make_thread_cpu_data
) (current_cpu
,
3154 ¤t_cpu
->cpu_data_placeholder
);
3155 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3156 H_GR_SP
, old_sp_buf
, 4);
3158 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3160 /* Find an unused slot. After a few threads have been created
3161 and exited, the array is expected to be a bit fragmented.
3162 We don't reuse the first entry, though, that of the
3164 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3165 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3166 /* Don't reuse a zombied entry. */
3167 && current_cpu
->thread_data
[i
].threadid
== 0)
3170 memcpy (¤t_cpu
->thread_data
[i
],
3171 ¤t_cpu
->thread_data
[threadno
],
3172 sizeof (current_cpu
->thread_data
[i
]));
3173 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3174 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3175 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3176 current_cpu
->thread_data
[i
].parent_threadid
3177 = current_cpu
->thread_data
[threadno
].threadid
;
3178 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3179 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3180 current_cpu
->thread_data
[i
].at_syscall
= 0;
3181 current_cpu
->thread_data
[i
].sigpending
= 0;
3182 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3183 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3184 current_cpu
->m1threads
= nthreads
;
3188 /* Better watch these in case they do something necessary. */
3189 case TARGET_SYS_socketcall
:
3190 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3193 case TARGET_SYS_set_thread_area
:
3194 /* Do the same error check as Linux. */
3197 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
3200 (*current_cpu
->set_target_thread_data
) (current_cpu
, arg1
);
3204 unimplemented_syscall
:
3207 = cris_unknown_syscall (current_cpu
, pc
,
3208 "Unimplemented syscall: %d "
3209 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3210 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3215 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3216 if (callnum
== TARGET_SYS_open
)
3218 current_cpu
->last_open_fd
= retval
;
3219 current_cpu
->last_open_flags
= arg2
;
3222 current_cpu
->last_syscall
= callnum
;
3224 /* A system call is a rescheduling point. For the time being, we don't
3225 reschedule anywhere else. */
3226 if (current_cpu
->m1threads
!= 0
3227 /* We need to schedule off from an exiting thread that is the
3229 || (current_cpu
->thread_data
!= NULL
3230 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3232 bfd_byte retval_buf
[4];
3234 current_cpu
->thread_data
[threadno
].last_execution
3235 = TARGET_TIME_MS (current_cpu
);
3236 bfd_putl32 (retval
, retval_buf
);
3237 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3239 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3240 reschedule (current_cpu
);
3242 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3243 retval
= bfd_getl32 (retval_buf
);
3249 /* Callback from simulator write saying that the pipe at (reader, writer)
3250 is now non-empty (so the writer should wait until the pipe is empty, at
3251 least not write to this or any other pipe). Simplest is to just wait
3252 until the pipe is empty. */
3255 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3256 int reader
, int writer
)
3258 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3259 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3261 /* It's the current thread: we just have to re-run the current
3262 syscall instruction (presumably "break 13") and change the syscall
3263 to the special simulator-wait code. Oh, and set a marker that
3264 we're waiting, so we can disambiguate the special call from a
3267 This function may be called multiple times between cris_pipe_empty,
3268 but we must avoid e.g. decreasing PC every time. Check fd markers
3270 if (cpu
->thread_data
== NULL
)
3272 sim_io_eprintf (CPU_STATE (cpu
),
3273 "Terminating simulation due to writing pipe rd:wr %d:%d"
3274 " from one single thread\n", reader
, writer
);
3275 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3276 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3278 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3280 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3281 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3282 /* FIXME: We really shouldn't change registers other than R10 in
3283 syscalls (like R9), here or elsewhere. */
3284 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3285 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3289 /* Callback from simulator close or read call saying that the pipe at
3290 (reader, writer) is now empty (so the writer can write again, perhaps
3291 leave a waiting state). If there are bytes remaining, they couldn't be
3292 consumed (perhaps due to the pipe closing). */
3295 cris_pipe_empty (host_callback
*cb
,
3300 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3301 SIM_DESC sd
= CPU_STATE (current_cpu_for_cb_callback
);
3302 bfd_byte r10_buf
[4];
3304 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3306 /* We need to find the thread that waits for this pipe. */
3307 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3308 if (cpu
->thread_data
[i
].cpu_context
3309 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3313 /* Temporarily switch to this cpu context, so we can change the
3314 PC by ordinary calls. */
3316 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3317 &cpu
->cpu_data_placeholder
,
3318 cpu
->thread_cpu_data_size
);
3319 memcpy (&cpu
->cpu_data_placeholder
,
3320 cpu
->thread_data
[i
].cpu_context
,
3321 cpu
->thread_cpu_data_size
);
3323 /* The return value is supposed to contain the number of
3324 written bytes, which is the number of bytes requested and
3325 returned at the write call. You might think the right
3326 thing is to adjust the return-value to be only the
3327 *consumed* number of bytes, but it isn't. We're only
3328 called if the pipe buffer is fully consumed or it is being
3329 closed, possibly with remaining bytes. For the latter
3330 case, the writer is still supposed to see success for
3331 PIPE_BUF bytes (a constant which we happen to know and is
3332 unlikely to change). The return value may also be a
3333 negative number; an error value. This case is covered
3334 because "remaining" is always >= 0. */
3335 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3336 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3337 if (retval
- remaining
> TARGET_PIPE_BUF
)
3339 bfd_putl32 (retval
- remaining
, r10_buf
);
3340 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3342 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3343 memcpy (cpu
->thread_data
[i
].cpu_context
,
3344 &cpu
->cpu_data_placeholder
,
3345 cpu
->thread_cpu_data_size
);
3346 memcpy (&cpu
->cpu_data_placeholder
,
3347 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3348 cpu
->thread_cpu_data_size
);
3349 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3350 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3357 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3360 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
3362 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
3368 /* Set target-specific callback data. */
3371 cris_set_callbacks (host_callback
*cb
)
3373 /* Yeargh, have to cast away constness to avoid warnings. */
3374 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3375 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3377 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3378 parameter to cb_store_target_endian will make st_size negative.
3379 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3380 *unsigned*, and/or add syntax for signed-ness. */
3381 cb
->stat_map
= stat_map
;
3382 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3383 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3384 cb
->pipe_empty
= cris_pipe_empty
;
3385 cb
->time
= cris_time
;
3388 /* Process an address exception. */
3391 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3392 unsigned int map
, int nr_bytes
, address_word addr
,
3393 transfer_type transfer
, sim_core_signals sig
)
3395 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,