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
116 #define TARGET_SYS_set_thread_area 243
117 #define TARGET_SYS_exit_group 252
119 #define TARGET_PROT_READ 0x1
120 #define TARGET_PROT_WRITE 0x2
121 #define TARGET_PROT_EXEC 0x4
122 #define TARGET_PROT_NONE 0x0
124 #define TARGET_MAP_SHARED 0x01
125 #define TARGET_MAP_PRIVATE 0x02
126 #define TARGET_MAP_TYPE 0x0f
127 #define TARGET_MAP_FIXED 0x10
128 #define TARGET_MAP_ANONYMOUS 0x20
129 #define TARGET_MAP_DENYWRITE 0x800
131 #define TARGET_CTL_KERN 1
132 #define TARGET_CTL_VM 2
133 #define TARGET_CTL_NET 3
134 #define TARGET_CTL_PROC 4
135 #define TARGET_CTL_FS 5
136 #define TARGET_CTL_DEBUG 6
137 #define TARGET_CTL_DEV 7
138 #define TARGET_CTL_BUS 8
139 #define TARGET_CTL_ABI 9
141 #define TARGET_CTL_KERN_VERSION 4
144 #define TARGET_MREMAP_MAYMOVE 1
145 #define TARGET_MREMAP_FIXED 2
147 #define TARGET_TCGETS 0x5401
149 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
151 /* Seconds since 1970-01-01 to the above date + 10 minutes;
152 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
153 #define TARGET_EPOCH 1230764410
155 /* Milliseconds since start of run. We use the number of syscalls to
156 avoid introducing noise in the execution time. */
157 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
159 /* Seconds as in time(2). */
160 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
162 #define TARGET_SCHED_OTHER 0
164 #define TARGET_RLIMIT_STACK 3
165 #define TARGET_RLIMIT_NOFILE 7
167 #define SIM_TARGET_MAX_THREADS 64
168 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
170 /* From linux/sched.h. */
171 #define TARGET_CSIGNAL 0x000000ff
172 #define TARGET_CLONE_VM 0x00000100
173 #define TARGET_CLONE_FS 0x00000200
174 #define TARGET_CLONE_FILES 0x00000400
175 #define TARGET_CLONE_SIGHAND 0x00000800
176 #define TARGET_CLONE_PID 0x00001000
177 #define TARGET_CLONE_PTRACE 0x00002000
178 #define TARGET_CLONE_VFORK 0x00004000
179 #define TARGET_CLONE_PARENT 0x00008000
180 #define TARGET_CLONE_THREAD 0x00010000
181 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
183 /* From asm-cris/poll.h. */
184 #define TARGET_POLLIN 1
186 /* From asm-cris/signal.h. */
187 #define TARGET_SIG_BLOCK 0
188 #define TARGET_SIG_UNBLOCK 1
189 #define TARGET_SIG_SETMASK 2
191 #define TARGET_SIG_DFL 0
192 #define TARGET_SIG_IGN 1
193 #define TARGET_SIG_ERR ((USI)-1)
195 #define TARGET_SIGHUP 1
196 #define TARGET_SIGINT 2
197 #define TARGET_SIGQUIT 3
198 #define TARGET_SIGILL 4
199 #define TARGET_SIGTRAP 5
200 #define TARGET_SIGABRT 6
201 #define TARGET_SIGIOT 6
202 #define TARGET_SIGBUS 7
203 #define TARGET_SIGFPE 8
204 #define TARGET_SIGKILL 9
205 #define TARGET_SIGUSR1 10
206 #define TARGET_SIGSEGV 11
207 #define TARGET_SIGUSR2 12
208 #define TARGET_SIGPIPE 13
209 #define TARGET_SIGALRM 14
210 #define TARGET_SIGTERM 15
211 #define TARGET_SIGSTKFLT 16
212 #define TARGET_SIGCHLD 17
213 #define TARGET_SIGCONT 18
214 #define TARGET_SIGSTOP 19
215 #define TARGET_SIGTSTP 20
216 #define TARGET_SIGTTIN 21
217 #define TARGET_SIGTTOU 22
218 #define TARGET_SIGURG 23
219 #define TARGET_SIGXCPU 24
220 #define TARGET_SIGXFSZ 25
221 #define TARGET_SIGVTALRM 26
222 #define TARGET_SIGPROF 27
223 #define TARGET_SIGWINCH 28
224 #define TARGET_SIGIO 29
225 #define TARGET_SIGPOLL SIGIO
226 /* Actually commented out in the kernel header. */
227 #define TARGET_SIGLOST 29
228 #define TARGET_SIGPWR 30
229 #define TARGET_SIGSYS 31
231 /* From include/asm-cris/signal.h. */
232 #define TARGET_SA_NOCLDSTOP 0x00000001
233 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
234 #define TARGET_SA_SIGINFO 0x00000004
235 #define TARGET_SA_ONSTACK 0x08000000
236 #define TARGET_SA_RESTART 0x10000000
237 #define TARGET_SA_NODEFER 0x40000000
238 #define TARGET_SA_RESETHAND 0x80000000
239 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
240 #define TARGET_SA_RESTORER 0x04000000
242 /* From linux/wait.h. */
243 #define TARGET_WNOHANG 1
244 #define TARGET_WUNTRACED 2
245 #define TARGET___WNOTHREAD 0x20000000
246 #define TARGET___WALL 0x40000000
247 #define TARGET___WCLONE 0x80000000
249 /* From linux/limits.h. */
250 #define TARGET_PIPE_BUF 4096
253 #define TARGET_R_OK 4
254 #define TARGET_W_OK 2
255 #define TARGET_X_OK 1
256 #define TARGET_F_OK 0
258 static const char stat_map
[] =
259 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
260 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
261 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
264 static const CB_TARGET_DEFS_MAP syscall_map
[] =
266 { CB_SYS_open
, TARGET_SYS_open
},
267 { CB_SYS_close
, TARGET_SYS_close
},
268 { CB_SYS_read
, TARGET_SYS_read
},
269 { CB_SYS_write
, TARGET_SYS_write
},
270 { CB_SYS_lseek
, TARGET_SYS_lseek
},
271 { CB_SYS_unlink
, TARGET_SYS_unlink
},
272 { CB_SYS_getpid
, TARGET_SYS_getpid
},
273 { CB_SYS_fstat
, TARGET_SYS_fstat64
},
274 { CB_SYS_lstat
, TARGET_SYS_lstat64
},
275 { CB_SYS_stat
, TARGET_SYS_stat64
},
276 { CB_SYS_pipe
, TARGET_SYS_pipe
},
277 { CB_SYS_rename
, TARGET_SYS_rename
},
278 { CB_SYS_truncate
, TARGET_SYS_truncate
},
279 { CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
283 /* An older, 32-bit-only stat mapping. */
284 static const char stat32_map
[] =
285 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
286 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
287 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
289 /* Map for calls using the 32-bit struct stat. Primarily used by the
290 newlib Linux mapping. */
291 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
293 { CB_SYS_fstat
, TARGET_SYS_fstat
},
294 { CB_SYS_stat
, TARGET_SYS_stat
},
298 /* Giving the true value for the running sim process will lead to
299 non-time-invariant behavior. */
300 #define TARGET_PID 42
302 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
303 we did, we'd still don't get a register number with the "16" offset. */
304 #define TARGET_SRP_REGNUM (16+11)
306 /* Extracted by applying
307 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
308 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
309 adjusting the synonyms. */
311 static const CB_TARGET_DEFS_MAP errno_map
[] =
419 { ENAMETOOLONG
, 36 },
578 { EDESTADDRREQ
, 89 },
589 #ifdef EPROTONOSUPPORT
590 { EPROTONOSUPPORT
, 93 },
592 #ifdef ESOCKTNOSUPPORT
593 { ESOCKTNOSUPPORT
, 94 },
599 { EPFNOSUPPORT
, 96 },
602 { EAFNOSUPPORT
, 97 },
608 { EADDRNOTAVAIL
, 99 },
614 { ENETUNREACH
, 101 },
620 { ECONNABORTED
, 103 },
638 { ETOOMANYREFS
, 109 },
644 { ECONNREFUSED
, 111 },
650 { EHOSTUNREACH
, 113 },
656 { EINPROGRESS
, 115 },
683 { EMEDIUMTYPE
, 124 },
688 /* Extracted by applying
689 perl -ne 'if ($_ =~ /^#define/) { split;
690 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
691 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
692 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
693 installation and removing synonyms and unnecessary items. Don't
694 forget the end-marker. */
696 /* These we treat specially, as they're used in the fcntl F_GETFL
697 syscall. For consistency, open_map is also manually edited to use
699 #define TARGET_O_ACCMODE 0x3
700 #define TARGET_O_RDONLY 0x0
701 #define TARGET_O_WRONLY 0x1
703 static const CB_TARGET_DEFS_MAP open_map
[] = {
705 { O_ACCMODE
, TARGET_O_ACCMODE
},
708 { O_RDONLY
, TARGET_O_RDONLY
},
711 { O_WRONLY
, TARGET_O_WRONLY
},
732 { O_NONBLOCK
, 0x800 },
744 { O_DIRECT
, 0x4000 },
747 { O_LARGEFILE
, 0x8000 },
750 { O_DIRECTORY
, 0x10000 },
753 { O_NOFOLLOW
, 0x20000 },
758 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
759 static SIM_CPU
*current_cpu_for_cb_callback
;
761 static int syscall_read_mem (host_callback
*, struct cb_syscall
*,
762 unsigned long, char *, int);
763 static int syscall_write_mem (host_callback
*, struct cb_syscall
*,
764 unsigned long, const char *, int);
765 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
767 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
769 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
771 static void dump_statistics (SIM_CPU
*current_cpu
);
772 static void make_first_thread (SIM_CPU
*current_cpu
);
774 /* Read/write functions for system call interface. */
777 syscall_read_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
778 struct cb_syscall
*sc
,
779 unsigned long taddr
, char *buf
, int bytes
)
781 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
782 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
784 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
788 syscall_write_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
789 struct cb_syscall
*sc
,
790 unsigned long taddr
, const char *buf
, int bytes
)
792 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
793 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
795 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
798 /* When we risk running self-modified code (as in trampolines), this is
799 called from special-case insns. The silicon CRIS CPU:s have enough
800 cache snooping implemented making this a simulator-only issue. Tests:
801 gcc.c-torture/execute/931002-1.c execution, -O3 -g
802 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
805 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
806 USI pc ATTRIBUTE_UNUSED
)
808 SIM_DESC sd
= CPU_STATE (current_cpu
);
811 if (USING_SCACHE_P (sd
))
812 scache_flush_cpu (current_cpu
);
816 /* Output statistics at the end of a run. */
818 dump_statistics (SIM_CPU
*current_cpu
)
820 SIM_DESC sd
= CPU_STATE (current_cpu
);
821 CRIS_MISC_PROFILE
*profp
822 = CPU_CRIS_MISC_PROFILE (current_cpu
);
823 unsigned64 total
= profp
->basic_cycle_count
;
824 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
826 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
827 what's included in the "total" count only. */
828 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
829 & FLAG_CRIS_MISC_PROFILE_ALL
)
831 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
834 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
836 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
837 total
+= profp
->unaligned_mem_dword_count
;
840 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
841 textmsg
= "Schedulable clock cycles, total @: %llu\n";
843 += (profp
->memsrc_stall_count
844 + profp
->memraw_stall_count
845 + profp
->movemsrc_stall_count
846 + profp
->movemdst_stall_count
847 + profp
->mulsrc_stall_count
848 + profp
->jumpsrc_stall_count
849 + profp
->unaligned_mem_dword_count
);
852 case FLAG_CRIS_MISC_PROFILE_ALL
:
853 textmsg
= "All accounted clock cycles, total @: %llu\n";
855 += (profp
->memsrc_stall_count
856 + profp
->memraw_stall_count
857 + profp
->movemsrc_stall_count
858 + profp
->movemdst_stall_count
859 + profp
->movemaddr_stall_count
860 + profp
->mulsrc_stall_count
861 + profp
->jumpsrc_stall_count
862 + profp
->branch_stall_count
863 + profp
->jumptarget_stall_count
864 + profp
->unaligned_mem_dword_count
);
871 "Internal inconsistency at %s:%d",
873 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
874 sim_stopped
, SIM_SIGILL
);
877 /* Historically, these messages have gone to stderr, so we'll keep it
878 that way. It's also easier to then tell it from normal program
879 output. FIXME: Add redirect option like "run -e file". */
880 sim_io_eprintf (sd
, textmsg
, total
);
882 /* For v32, unaligned_mem_dword_count should always be 0. For
883 v10, memsrc_stall_count should always be 0. */
884 sim_io_eprintf (sd
, "Memory source stall cycles: %llu\n",
885 (unsigned long long) (profp
->memsrc_stall_count
886 + profp
->unaligned_mem_dword_count
));
887 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %llu\n",
888 (unsigned long long) profp
->memraw_stall_count
);
889 sim_io_eprintf (sd
, "Movem source stall cycles: %llu\n",
890 (unsigned long long) profp
->movemsrc_stall_count
);
891 sim_io_eprintf (sd
, "Movem destination stall cycles: %llu\n",
892 (unsigned long long) profp
->movemdst_stall_count
);
893 sim_io_eprintf (sd
, "Movem address stall cycles: %llu\n",
894 (unsigned long long) profp
->movemaddr_stall_count
);
895 sim_io_eprintf (sd
, "Multiplication source stall cycles: %llu\n",
896 (unsigned long long) profp
->mulsrc_stall_count
);
897 sim_io_eprintf (sd
, "Jump source stall cycles: %llu\n",
898 (unsigned long long) profp
->jumpsrc_stall_count
);
899 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %llu\n",
900 (unsigned long long) profp
->branch_stall_count
);
901 sim_io_eprintf (sd
, "Jump target stall cycles: %llu\n",
902 (unsigned long long) profp
->jumptarget_stall_count
);
905 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
906 Return 1 if a overlap detected, 0 otherwise. */
909 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
910 struct cris_sim_mmapped_page
**rootp
,
913 struct cris_sim_mmapped_page
*mapp
;
915 if (len
== 0 || (len
& 8191))
918 /* Iterate over the reverse-address sorted pages until we find a page in
919 or lower than the checked area. */
920 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
921 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
927 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
928 Return 1 if the whole area is mapped, 0 otherwise. */
931 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
932 struct cris_sim_mmapped_page
**rootp
,
935 struct cris_sim_mmapped_page
*mapp
;
937 if (len
== 0 || (len
& 8191))
940 /* Iterate over the reverse-address sorted pages until we find a page
941 lower than the checked area. */
942 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
943 if (addr
== mapp
->addr
&& len
== 8192)
945 else if (addr
+ len
> mapp
->addr
)
951 /* Debug helper; to be run from gdb. */
954 cris_dump_map (SIM_CPU
*current_cpu
)
956 struct cris_sim_mmapped_page
*mapp
;
959 for (mapp
= current_cpu
->highest_mmapped_page
,
960 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
961 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
965 if (mapp
->addr
!= start
- 8192)
967 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
968 end
= mapp
->addr
+ 8191;
974 if (current_cpu
->highest_mmapped_page
!= NULL
)
975 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
978 /* Create mmapped memory. */
981 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
984 struct cris_sim_mmapped_page
*mapp
;
985 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
986 USI new_addr
= 0x40000000;
991 new_addr
= rootp
[0]->addr
+ 8192;
998 /* Which is better: return an error for this, or just round it up? */
1001 /* Do a recursive call for each page in the request. */
1002 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
1003 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
1010 mapp
!= NULL
&& mapp
->addr
> new_addr
;
1012 higher_prevp
= &mapp
->prev
;
1014 /* Allocate the new page, on the next higher page from the last one
1015 allocated, and link in the new descriptor before previous ones. */
1016 mapp
= malloc (sizeof (*mapp
));
1019 return (USI
) -ENOMEM
;
1021 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1025 mapp
->addr
= new_addr
;
1026 mapp
->prev
= *higher_prevp
;
1027 *higher_prevp
= mapp
;
1032 /* Unmap one or more pages. */
1035 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1038 struct cris_sim_mmapped_page
*mapp
;
1039 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1046 /* Which is better: return an error for this, or just round it up? */
1049 /* Loop backwards to make each call is O(1) over the number of pages
1050 allocated, if we're unmapping from the high end of the pages. */
1051 for (page_addr
= addr
+ len
- 8192;
1054 if (unmap_pages (sd
, rootp
, page_addr
, 8192) != 0)
1060 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1061 higher_prevp
= &mapp
->prev
;
1063 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1066 *higher_prevp
= mapp
->prev
;
1067 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1072 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1075 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1077 SIM_DESC sd
= CPU_STATE (current_cpu
);
1079 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1083 /* Handlers from the CGEN description that should not be called. */
1086 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1087 UINT srcreg ATTRIBUTE_UNUSED
,
1088 USI dstreg ATTRIBUTE_UNUSED
)
1094 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1095 UINT index ATTRIBUTE_UNUSED
,
1096 USI page ATTRIBUTE_UNUSED
,
1097 USI newval ATTRIBUTE_UNUSED
)
1103 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1104 UINT index ATTRIBUTE_UNUSED
,
1105 USI page ATTRIBUTE_UNUSED
)
1110 /* Swap one context for another. */
1113 schedule (SIM_CPU
*current_cpu
, int next
)
1115 /* Need to mark context-switches in the trace output. */
1116 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1117 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1118 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1121 /* Copy the current context (if there is one) to its slot. */
1122 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1123 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1124 ¤t_cpu
->cpu_data_placeholder
,
1125 current_cpu
->thread_cpu_data_size
);
1127 /* Copy the new context from its slot. */
1128 memcpy (¤t_cpu
->cpu_data_placeholder
,
1129 current_cpu
->thread_data
[next
].cpu_context
,
1130 current_cpu
->thread_cpu_data_size
);
1132 /* Update needed stuff to indicate the new context. */
1133 current_cpu
->threadno
= next
;
1135 /* Handle pending signals. */
1136 if (current_cpu
->thread_data
[next
].sigpending
1137 /* We don't run nested signal handlers. This means that pause(2)
1138 and sigsuspend(2) do not work in sighandlers, but that
1139 shouldn't be too hard a restriction. It also greatly
1140 simplifies the code. */
1141 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1145 /* See if there's really a pending, non-blocked handler. We don't
1146 queue signals, so just use the first one in ascending order. */
1147 for (sig
= 0; sig
< 64; sig
++)
1148 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1149 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1155 USI pc
= sim_pc_get (current_cpu
);
1157 /* It's simpler to save the CPU context inside the simulator
1158 than on the stack. */
1159 current_cpu
->thread_data
[next
].cpu_context_atsignal
1161 ->make_thread_cpu_data
) (current_cpu
,
1162 current_cpu
->thread_data
[next
]
1165 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1166 sp
= bfd_getl32 (regbuf
);
1168 /* Make sure we have an aligned stack. */
1171 /* Make room for the signal frame, aligned. FIXME: Check that
1172 the memory exists, map it in if absent. (BTW, should also
1173 implement on-access automatic stack allocation). */
1176 /* This isn't the same signal frame as the kernel uses, because
1177 we don't want to bother getting all registers on and off the
1180 /* First, we store the currently blocked signals. */
1182 for (i
= 0; i
< 32; i
++)
1184 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1185 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1187 for (i
= 0; i
< 31; i
++)
1189 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1190 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1192 /* Then, the actual instructions. This is CPU-specific, but we
1193 use instructions from the common subset for v10 and v32 which
1194 should be safe for the time being but could be parametrized
1196 /* MOVU.W [PC+],R9. */
1197 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1198 /* .WORD TARGET_SYS_sigreturn. */
1199 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1200 TARGET_SYS_sigreturn
);
1202 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1204 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1205 instruction. Still, it doesn't matter because v10 has no
1206 delay slot for BREAK so it will not be executed). */
1207 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1209 /* Modify registers to hold the right values for the sighandler
1210 context: updated stackpointer and return address pointing to
1211 the sigreturn stub. */
1212 bfd_putl32 (sp
, regbuf
);
1213 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1214 bfd_putl32 (sp
+ 8, regbuf
);
1215 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1218 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1220 /* Block this signal (for the duration of the sighandler). */
1221 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1223 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1224 bfd_putl32 (sig
, regbuf
);
1225 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1228 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1229 needed all this for, specifies a SA_SIGINFO call but treats it
1230 like an ordinary sighandler; only the signal number argument is
1231 inspected. To make future need to implement SA_SIGINFO
1232 correctly possible, we set the siginfo argument register to a
1233 magic (hopefully non-address) number. (NB: then, you should
1234 just need to pass the siginfo argument; it seems you probably
1235 don't need to implement the specific rt_sigreturn.) */
1236 bfd_putl32 (0xbad5161f, regbuf
);
1237 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1240 /* The third argument is unused and the kernel sets it to 0. */
1241 bfd_putl32 (0, regbuf
);
1242 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1247 /* No, there actually was no pending signal for this thread. Reset
1249 current_cpu
->thread_data
[next
].sigpending
= 0;
1253 /* Reschedule the simplest possible way until something else is absolutely
1255 - A. Find the next process (round-robin) that doesn't have at_syscall
1257 - B. If there is none, just run the next process, round-robin.
1258 - Clear at_syscall for the current process. */
1261 reschedule (SIM_CPU
*current_cpu
)
1265 /* Iterate over all thread slots, because after a few thread creations
1266 and exits, we don't know where the live ones are. */
1267 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1268 i
!= current_cpu
->threadno
;
1269 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1270 if (current_cpu
->thread_data
[i
].cpu_context
1271 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1273 schedule (current_cpu
, i
);
1277 /* Pick any next live thread. */
1278 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1279 i
!= current_cpu
->threadno
;
1280 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1281 if (current_cpu
->thread_data
[i
].cpu_context
)
1283 schedule (current_cpu
, i
);
1287 /* More than one live thread, but we couldn't find the next one? */
1291 /* Set up everything to receive (or IGN) an incoming signal to the
1295 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1298 USI pc
= sim_pc_get (current_cpu
);
1300 /* Find the thread index of the pid. */
1301 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1302 /* Apparently it's ok to send signals to zombies (so a check for
1303 current_cpu->thread_data[i].cpu_context != NULL would be
1305 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1308 switch (current_cpu
->sighandler
[sig
])
1310 case TARGET_SIG_DFL
:
1313 /* The following according to the glibc
1314 documentation. (The kernel code has non-obvious
1315 execution paths.) */
1318 case TARGET_SIGSEGV
:
1320 case TARGET_SIGABRT
:
1321 case TARGET_SIGTRAP
:
1324 case TARGET_SIGTERM
:
1326 case TARGET_SIGQUIT
:
1327 case TARGET_SIGKILL
:
1330 case TARGET_SIGALRM
:
1331 case TARGET_SIGVTALRM
:
1332 case TARGET_SIGPROF
:
1333 case TARGET_SIGSTOP
:
1335 case TARGET_SIGPIPE
:
1336 case TARGET_SIGLOST
:
1337 case TARGET_SIGXCPU
:
1338 case TARGET_SIGXFSZ
:
1339 case TARGET_SIGUSR1
:
1340 case TARGET_SIGUSR2
:
1341 sim_io_eprintf (CPU_STATE (current_cpu
),
1342 "Exiting pid %d due to signal %d\n",
1344 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1345 NULL
, pc
, sim_stopped
,
1346 sig
== TARGET_SIGABRT
1347 ? SIM_SIGABRT
: SIM_SIGILL
);
1350 /* The default for all other signals is to be ignored. */
1355 case TARGET_SIG_IGN
:
1358 case TARGET_SIGKILL
:
1359 case TARGET_SIGSTOP
:
1360 /* Can't ignore these signals. */
1361 sim_io_eprintf (CPU_STATE (current_cpu
),
1362 "Exiting pid %d due to signal %d\n",
1364 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1365 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1374 /* Mark the signal as pending, making schedule () check
1375 closer. The signal will be handled when the thread is
1376 scheduled and the signal is unblocked. */
1377 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1378 current_cpu
->thread_data
[i
].sigpending
= 1;
1383 sim_io_eprintf (CPU_STATE (current_cpu
),
1384 "Unimplemented signal: %d\n", sig
);
1385 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1386 sim_stopped
, SIM_SIGILL
);
1391 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1395 /* Make the vector and the first item, the main thread. */
1398 make_first_thread (SIM_CPU
*current_cpu
)
1400 current_cpu
->thread_data
1402 SIM_TARGET_MAX_THREADS
1403 * sizeof (current_cpu
->thread_data
[0]));
1404 current_cpu
->thread_data
[0].cpu_context
1405 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1407 ->cpu_data_placeholder
);
1408 current_cpu
->thread_data
[0].parent_threadid
= -1;
1410 /* For good measure. */
1411 if (TARGET_SIG_DFL
!= 0)
1415 /* Handle unknown system calls. Returns (if it does) the syscall
1419 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1421 SIM_DESC sd
= CPU_STATE (current_cpu
);
1422 host_callback
*cb
= STATE_CALLBACK (sd
);
1424 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1425 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1430 sim_io_evprintf (sd
, s
, ap
);
1433 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1434 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1437 return -cb_host_to_target_errno (cb
, ENOSYS
);
1440 /* Main function: the handler of the "break 13" syscall insn. */
1443 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1444 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1448 SIM_DESC sd
= CPU_STATE (current_cpu
);
1449 host_callback
*cb
= STATE_CALLBACK (sd
);
1451 int threadno
= current_cpu
->threadno
;
1453 current_cpu
->syscalls
++;
1455 CB_SYSCALL_INIT (&s
);
1461 if (callnum
== TARGET_SYS_exit_group
1462 || (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0))
1464 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1465 & FLAG_CRIS_MISC_PROFILE_ALL
)
1466 dump_statistics (current_cpu
);
1467 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1471 s
.p2
= (PTR
) current_cpu
;
1472 s
.read_mem
= syscall_read_mem
;
1473 s
.write_mem
= syscall_write_mem
;
1475 current_cpu_for_cb_callback
= current_cpu
;
1477 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1480 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1482 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1485 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1487 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1489 /* If the generic simulator call said ENOSYS, then let's try the
1490 ones we know ourselves.
1492 The convention is to provide *very limited* functionality on an
1493 as-needed basis, only what's covered by the test-suite, tests
1494 added when functionality changes and abort with a descriptive
1495 message for *everything* else. Where there's no test-case, we
1500 /* It's a pretty safe bet that the "old setup() system call"
1501 number will not be re-used; we can't say the same for higher
1502 numbers. We treat this simulator-generated call as "wait
1503 forever"; we re-run this insn. The wait is ended by a
1504 callback. Sanity check that this is the reason we got
1506 if (current_cpu
->thread_data
== NULL
1507 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1508 goto unimplemented_syscall
;
1510 sim_pc_set (current_cpu
, pc
);
1514 case TARGET_SYS_fcntl64
:
1515 case TARGET_SYS_fcntl
:
1520 Glibc checks stdin, stdout and stderr fd:s for
1521 close-on-exec security sanity. We just need to provide a
1522 OK return value. If we really need to have a
1523 close-on-exec flag true, we could just do a real fcntl
1529 /* F_SETFD. Just ignore attempts to set the close-on-exec
1535 /* F_GETFL. Check for the special case for open+fdopen. */
1536 if (current_cpu
->last_syscall
== TARGET_SYS_open
1537 && arg1
== current_cpu
->last_open_fd
)
1539 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1544 /* Because we can't freopen fd:s 0, 1, 2 to mean
1545 something else than stdin, stdout and stderr
1546 (sim/common/syscall.c:cb_syscall special cases fd
1547 0, 1 and 2), we know what flags that we can
1548 sanely return for these fd:s. */
1549 retval
= TARGET_O_RDONLY
;
1552 else if (arg1
== 1 || arg1
== 2)
1554 retval
= TARGET_O_WRONLY
;
1559 /* Nothing else is implemented. */
1561 = cris_unknown_syscall (current_cpu
, pc
,
1562 "Unimplemented %s syscall "
1563 "(fd: 0x%lx: cmd: 0x%lx arg: "
1565 callnum
== TARGET_SYS_fcntl
1566 ? "fcntl" : "fcntl64",
1567 (unsigned long) (USI
) arg1
,
1568 (unsigned long) (USI
) arg2
,
1569 (unsigned long) (USI
) arg3
);
1574 case TARGET_SYS_uname
:
1576 /* Fill in a few constants to appease glibc. */
1577 static char sim_utsname
[6][65] =
1583 "cris", /* Overwritten below. */
1587 /* Having the hardware type in Linux equal to the bfd
1588 printable name is deliberate: if you make config.guess
1589 work on your Linux-type system the usual way, it
1590 probably will; either the bfd printable_name or the
1591 ambiguous arch_name. */
1592 strcpy (sim_utsname
[4], STATE_ARCHITECTURE (sd
)->printable_name
);
1594 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1595 sizeof (sim_utsname
))
1596 != sizeof (sim_utsname
))
1597 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1603 case TARGET_SYS_geteuid32
:
1604 /* We tell the truth with these. Maybe we shouldn't, but it
1605 should match the "stat" information. */
1606 retval
= geteuid ();
1609 case TARGET_SYS_getuid32
:
1613 case TARGET_SYS_getegid32
:
1614 retval
= getegid ();
1617 case TARGET_SYS_getgid32
:
1621 case TARGET_SYS_brk
:
1622 /* Most often, we just return the argument, like the Linux
1627 retval
= current_cpu
->endbrk
;
1628 else if (arg1
<= current_cpu
->endmem
)
1629 current_cpu
->endbrk
= arg1
;
1632 USI new_end
= (arg1
+ 8191) & ~8191;
1634 /* If the simulator wants to brk more than a certain very
1635 large amount, something is wrong. FIXME: Return an error
1636 or abort? Have command-line selectable? */
1637 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1639 current_cpu
->endbrk
= current_cpu
->endmem
;
1640 retval
= current_cpu
->endmem
;
1644 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1645 current_cpu
->endmem
,
1646 new_end
- current_cpu
->endmem
,
1648 current_cpu
->endbrk
= arg1
;
1649 current_cpu
->endmem
= new_end
;
1653 case TARGET_SYS_getpid
:
1654 /* Correct until CLONE_THREAD is implemented. */
1655 retval
= current_cpu
->thread_data
== NULL
1657 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1660 case TARGET_SYS_getppid
:
1661 /* Correct until CLONE_THREAD is implemented. */
1662 retval
= current_cpu
->thread_data
== NULL
1665 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1668 case TARGET_SYS_mmap2
:
1677 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1678 still masked away this bit, so let's just ignore
1680 flags
&= ~TARGET_MAP_DENYWRITE
;
1682 /* If the simulator wants to mmap more than the very large
1683 limit, something is wrong. FIXME: Return an error or
1684 abort? Have command-line selectable? */
1685 if (len
> SIM_MAX_ALLOC_CHUNK
)
1687 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1691 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1693 != (TARGET_PROT_READ
1695 | TARGET_PROT_EXEC
))
1696 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1697 && prot
!= TARGET_PROT_READ
)
1698 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1699 && flags
!= TARGET_MAP_PRIVATE
1700 && flags
!= (TARGET_MAP_ANONYMOUS
1701 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1702 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1703 && flags
!= TARGET_MAP_SHARED
)
1705 && prot
!= TARGET_PROT_READ
1706 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1707 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1708 || (fd
== (USI
) -1 && pgoff
!= 0)
1709 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
))
1710 || ((flags
& TARGET_MAP_FIXED
) == 0
1711 && is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1712 addr
, (len
+ 8191) & ~8191)))
1715 = cris_unknown_syscall (current_cpu
, pc
,
1716 "Unimplemented mmap2 call "
1717 "(0x%lx, 0x%lx, 0x%lx, "
1718 "0x%lx, 0x%lx, 0x%lx)\n",
1719 (unsigned long) arg1
,
1720 (unsigned long) arg2
,
1721 (unsigned long) arg3
,
1722 (unsigned long) arg4
,
1723 (unsigned long) arg5
,
1724 (unsigned long) arg6
);
1727 else if (fd
!= (USI
) -1)
1734 /* A non-aligned argument is allowed for files. */
1735 USI newlen
= (len
+ 8191) & ~8191;
1737 /* We only support read, read|exec, and read|write,
1738 which we should already have checked. Check again
1740 if (prot
!= TARGET_PROT_READ
1741 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1742 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1745 if ((flags
& TARGET_MAP_FIXED
)
1746 && unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1751 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1754 if (newaddr
>= (USI
) -8191)
1757 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1761 /* We were asked for MAP_FIXED, but couldn't. */
1762 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1765 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1767 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1771 /* Find the current position in the file. */
1772 s
.func
= TARGET_SYS_lseek
;
1776 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1783 /* Move to the correct offset in the file. */
1784 s
.func
= TARGET_SYS_lseek
;
1786 s
.arg2
= pgoff
*8192;
1788 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1794 /* Use the standard read callback to read in "len"
1796 s
.func
= TARGET_SYS_read
;
1800 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1803 if ((USI
) s
.result
!= len
)
1806 /* After reading, we need to go back to the previous
1807 position in the file. */
1808 s
.func
= TARGET_SYS_lseek
;
1812 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1814 if (pos
!= (USI
) s
.result
)
1821 USI newlen
= (len
+ 8191) & ~8191;
1824 if ((flags
& TARGET_MAP_FIXED
)
1825 && unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1829 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1832 if (newaddr
>= (USI
) -8191)
1833 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1837 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1840 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1842 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1849 case TARGET_SYS_mprotect
:
1851 /* We only cover the case of linuxthreads mprotecting out
1852 its stack guard page and of dynamic loading mprotecting
1853 away the data (for some reason the whole library, then
1854 mprotects away the data part and mmap-FIX:es it again. */
1859 if (prot
!= TARGET_PROT_NONE
1860 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1861 addr
, (len
+ 8191) & ~8191))
1864 = cris_unknown_syscall (current_cpu
, pc
,
1865 "Unimplemented mprotect call "
1866 "(0x%lx, 0x%lx, 0x%lx)\n",
1867 (unsigned long) arg1
,
1868 (unsigned long) arg2
,
1869 (unsigned long) arg3
);
1873 /* Just ignore this. We could make this equal to munmap,
1874 but then we'd have to make sure no anon mmaps gets this
1875 address before a subsequent MAP_FIXED mmap intended to
1881 case TARGET_SYS_ioctl
:
1883 /* We support only a very limited functionality: checking
1884 stdout with TCGETS to perform the isatty function. The
1885 TCGETS ioctl isn't actually performed or the result used by
1886 an isatty () caller in a "hello, world" program; only the
1887 return value is then used. Maybe we shouldn't care about
1888 the environment of the simulator regarding isatty, but
1889 that's been working before, in the xsim simulator. */
1890 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1891 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1893 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1897 case TARGET_SYS_munmap
:
1902 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1904 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1908 case TARGET_SYS_wait4
:
1916 /* FIXME: We're not properly implementing __WCLONE, and we
1917 don't really need the special casing so we might as well
1918 make this general. */
1919 if ((!(pid
== (USI
) -1
1920 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1923 && (options
== TARGET___WCLONE
1924 || options
== TARGET___WALL
)))
1926 || current_cpu
->thread_data
== NULL
)
1929 = cris_unknown_syscall (current_cpu
, pc
,
1930 "Unimplemented wait4 call "
1931 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1932 (unsigned long) arg1
,
1933 (unsigned long) arg2
,
1934 (unsigned long) arg3
,
1935 (unsigned long) arg4
);
1939 if (pid
== (USI
) -1)
1940 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1942 if (current_cpu
->thread_data
[threadno
].threadid
1943 == current_cpu
->thread_data
[i
].parent_threadid
1944 && current_cpu
->thread_data
[i
].threadid
!= 0
1945 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1947 /* A zombied child. Get the exit value and clear the
1948 zombied entry so it will be reused. */
1949 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1951 ->thread_data
[i
].exitval
);
1953 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1954 memset (¤t_cpu
->thread_data
[i
], 0,
1955 sizeof (current_cpu
->thread_data
[i
]));
1961 /* We're waiting for a specific PID. If we don't find
1962 it zombied on this run, rerun the syscall. */
1963 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1964 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1965 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1968 /* Get the exit value if the caller wants it. */
1969 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1976 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1977 memset (¤t_cpu
->thread_data
[i
], 0,
1978 sizeof (current_cpu
->thread_data
[i
]));
1983 sim_pc_set (current_cpu
, pc
);
1986 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1991 case TARGET_SYS_rt_sigaction
:
1999 __sighandler_t sa_handler;
2000 unsigned long sa_flags;
2001 void (*sa_restorer)(void);
2007 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
2008 current_cpu
->sighandler
[signum
]);
2009 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
2010 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
2012 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2013 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
2014 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
2018 USI target_sa_handler
2019 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2021 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2022 USI target_sa_restorer
2023 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2024 USI target_sa_mask_low
2025 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2026 USI target_sa_mask_high
2027 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2029 /* We won't interrupt a syscall so we won't restart it,
2030 but a signal(2) call ends up syscalling rt_sigaction
2031 with this flag, so we have to handle it. The
2032 sa_restorer field contains garbage when not
2033 TARGET_SA_RESTORER, so don't look at it. For the
2034 time being, we don't nest sighandlers, so we
2035 ignore the sa_mask, which simplifies things. */
2036 if ((target_sa_flags
!= 0
2037 && target_sa_flags
!= TARGET_SA_RESTART
2038 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2039 || target_sa_handler
== 0)
2042 = cris_unknown_syscall (current_cpu
, pc
,
2043 "Unimplemented rt_sigaction "
2046 "[0x%x, 0x%x, 0x%x, "
2047 "{0x%x, 0x%x}], 0x%lx)\n",
2048 (unsigned long) arg1
,
2049 (unsigned long) arg2
,
2054 target_sa_mask_high
,
2055 (unsigned long) arg3
);
2059 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2061 /* Because we may have unblocked signals, one may now be
2062 pending, if there are threads, that is. */
2063 if (current_cpu
->thread_data
)
2064 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2070 case TARGET_SYS_mremap
:
2076 USI new_addr
= arg5
;
2079 if (new_len
== old_len
)
2080 /* The program and/or library is possibly confused but
2081 this is a valid call. Happens with ipps-1.40 on file
2084 else if (new_len
< old_len
)
2086 /* Shrinking is easy. */
2087 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2088 addr
+ new_len
, old_len
- new_len
) != 0)
2089 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2093 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2094 addr
+ old_len
, new_len
- old_len
))
2096 /* If the extension isn't mapped, we can just add it. */
2098 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2099 addr
+ old_len
, new_len
- old_len
);
2101 if (mapped_addr
> (USI
) -8192)
2102 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2106 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2108 /* Create a whole new map and copy the contents
2109 block-by-block there. We ignore the new_addr argument
2112 USI prev_addr
= addr
;
2113 USI prev_len
= old_len
;
2116 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2119 if (mapped_addr
> (USI
) -8192)
2121 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2125 retval
= mapped_addr
;
2128 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2130 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2132 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2133 mapped_addr
, 8192) != 8192)
2137 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2138 prev_addr
, prev_len
) != 0)
2142 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2146 case TARGET_SYS_poll
:
2148 int npollfds
= arg2
;
2164 /* Check that this is the expected poll call from
2165 linuxthreads/manager.c; we don't support anything else.
2166 Remember, fd == 0 isn't supported. */
2168 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2170 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2173 || ((cb
->fstat
) (cb
, fd
, &buf
) != 0
2174 || (buf
.st_mode
& S_IFIFO
) == 0)
2175 || current_cpu
->thread_data
== NULL
)
2178 = cris_unknown_syscall (current_cpu
, pc
,
2179 "Unimplemented poll syscall "
2180 "(0x%lx: [0x%x, 0x%x, x], "
2182 (unsigned long) arg1
, fd
, events
,
2183 (unsigned long) arg2
,
2184 (unsigned long) arg3
);
2190 /* Iterate over threads; find a marker that a writer is
2191 sleeping, waiting for a reader. */
2192 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2193 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2194 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2196 revents
= TARGET_POLLIN
;
2201 /* Timeout decreases with whatever time passed between the
2202 last syscall and this. That's not exactly right for the
2203 first call, but it's close enough that it isn't
2204 worthwhile to complicate matters by making that a special
2207 -= (TARGET_TIME_MS (current_cpu
)
2208 - (current_cpu
->thread_data
[threadno
].last_execution
));
2210 /* Arrange to repeat this syscall until timeout or event,
2211 decreasing timeout at each iteration. */
2212 if (timeout
> 0 && revents
== 0)
2214 bfd_byte timeout_buf
[4];
2216 bfd_putl32 (timeout
, timeout_buf
);
2217 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2218 H_GR_R12
, timeout_buf
, 4);
2219 sim_pc_set (current_cpu
, pc
);
2224 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2229 case TARGET_SYS_time
:
2231 retval
= (int) (*cb
->time
) (cb
, 0L);
2233 /* At time of this writing, CB_SYSCALL_time doesn't do the
2234 part of setting *arg1 to the return value. */
2236 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2240 case TARGET_SYS_gettimeofday
:
2243 USI ts
= TARGET_TIME (current_cpu
);
2244 USI tms
= TARGET_TIME_MS (current_cpu
);
2246 /* First dword is seconds since TARGET_EPOCH. */
2247 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2249 /* Second dword is microseconds. */
2250 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2251 (tms
% 1000) * 1000);
2255 /* Time-zone info is always cleared. */
2256 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2257 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2262 case TARGET_SYS_llseek
:
2264 /* If it fits, tweak parameters to fit the "generic" 32-bit
2265 lseek and use that. */
2273 if (!((offs_hi
== 0 && offs_lo
>= 0)
2274 || (offs_hi
== -1 && offs_lo
< 0)))
2277 = cris_unknown_syscall (current_cpu
, pc
,
2278 "Unimplemented llseek offset,"
2279 " fd %d: 0x%x:0x%x\n",
2280 fd
, (unsigned) arg2
,
2285 s
.func
= TARGET_SYS_lseek
;
2288 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2290 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2292 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2295 retval
= -s
.errcode
;
2298 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2300 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2301 s
.result
< 0 ? -1 : 0);
2306 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2309 void *iov_base; Starting address
2310 size_t iov_len; Number of bytes to transfer
2312 case TARGET_SYS_writev
:
2320 /* We'll ignore strict error-handling and just do multiple write calls. */
2321 for (i
= 0; i
< iovcnt
; i
++)
2325 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2328 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2331 s
.func
= TARGET_SYS_write
;
2336 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2338 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2340 if (sysret
!= iov_len
)
2355 /* This one does have a generic callback function, but at the time
2356 of this writing, cb_syscall does not have code for it, and we
2357 need target-specific code for the threads implementation
2359 case TARGET_SYS_kill
:
2366 /* At kill(2), glibc sets signal masks such that the thread
2367 machinery is initialized. Still, there is and was only
2369 if (current_cpu
->max_threadid
== 0)
2371 if (pid
!= TARGET_PID
)
2373 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2377 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2378 if (sig
== TARGET_SIGABRT
)
2379 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2380 the end-point for failing GCC test-cases. */
2381 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2385 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2386 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2390 /* This will not be reached. */
2394 retval
= deliver_signal (current_cpu
, sig
, pid
);
2398 case TARGET_SYS_rt_sigprocmask
:
2405 if (how
!= TARGET_SIG_BLOCK
2406 && how
!= TARGET_SIG_SETMASK
2407 && how
!= TARGET_SIG_UNBLOCK
)
2410 = cris_unknown_syscall (current_cpu
, pc
,
2411 "Unimplemented rt_sigprocmask "
2412 "syscall (0x%x, 0x%x, 0x%x)\n",
2420 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2423 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2426 /* The sigmask is kept in the per-thread data, so we may
2427 need to create the first one. */
2428 if (current_cpu
->thread_data
== NULL
)
2429 make_first_thread (current_cpu
);
2431 if (how
== TARGET_SIG_SETMASK
)
2432 for (i
= 0; i
< 64; i
++)
2433 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2435 for (i
= 0; i
< 32; i
++)
2436 if ((set_low
& (1 << i
)))
2437 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2438 = (how
!= TARGET_SIG_UNBLOCK
);
2440 for (i
= 0; i
< 31; i
++)
2441 if ((set_high
& (1 << i
)))
2442 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2443 = (how
!= TARGET_SIG_UNBLOCK
);
2445 /* The mask changed, so a signal may be unblocked for
2447 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2455 for (i
= 0; i
< 32; i
++)
2456 if (current_cpu
->thread_data
[threadno
]
2457 .sigdata
[i
+ 1].blocked
)
2459 for (i
= 0; i
< 31; i
++)
2460 if (current_cpu
->thread_data
[threadno
]
2461 .sigdata
[i
+ 33].blocked
)
2464 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2465 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2472 case TARGET_SYS_sigreturn
:
2476 int was_sigsuspended
;
2478 if (current_cpu
->thread_data
== NULL
2479 /* The CPU context is saved with the simulator data, not
2480 on the stack as in the real world. */
2481 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2485 = cris_unknown_syscall (current_cpu
, pc
,
2486 "Invalid sigreturn syscall: "
2487 "no signal handler active "
2488 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2490 (unsigned long) arg1
,
2491 (unsigned long) arg2
,
2492 (unsigned long) arg3
,
2493 (unsigned long) arg4
,
2494 (unsigned long) arg5
,
2495 (unsigned long) arg6
);
2500 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2502 /* Restore the sigmask, either from the stack copy made when
2503 the sighandler was called, or from the saved state
2504 specifically for sigsuspend(2). */
2505 if (was_sigsuspended
)
2507 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2508 for (i
= 0; i
< 64; i
++)
2509 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2510 = current_cpu
->thread_data
[threadno
]
2511 .sigdata
[i
].blocked_suspendsave
;
2519 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2520 H_GR_SP
, regbuf
, 4);
2521 sp
= bfd_getl32 (regbuf
);
2523 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2525 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2527 for (i
= 0; i
< 32; i
++)
2528 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2529 = (set_low
& (1 << i
)) != 0;
2530 for (i
= 0; i
< 31; i
++)
2531 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2532 = (set_high
& (1 << i
)) != 0;
2535 /* The mask changed, so a signal may be unblocked for
2537 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2539 memcpy (¤t_cpu
->cpu_data_placeholder
,
2540 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2541 current_cpu
->thread_cpu_data_size
);
2542 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2543 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2545 /* The return value must come from the saved R10. */
2546 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2547 retval
= bfd_getl32 (regbuf
);
2549 /* We must also break the "sigsuspension loop". */
2550 if (was_sigsuspended
)
2551 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2555 case TARGET_SYS_rt_sigsuspend
:
2563 = cris_unknown_syscall (current_cpu
, pc
,
2564 "Unimplemented rt_sigsuspend syscall"
2565 " arguments (0x%lx, 0x%lx)\n",
2566 (unsigned long) arg1
,
2567 (unsigned long) arg2
);
2571 /* Don't change the signal mask if we're already in
2572 sigsuspend state (i.e. this syscall is a rerun). */
2573 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2576 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2579 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2583 /* Save the current sigmask and insert the user-supplied
2585 for (i
= 0; i
< 32; i
++)
2587 current_cpu
->thread_data
[threadno
]
2588 .sigdata
[i
+ 1].blocked_suspendsave
2589 = current_cpu
->thread_data
[threadno
]
2590 .sigdata
[i
+ 1].blocked
;
2592 current_cpu
->thread_data
[threadno
]
2593 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2595 for (i
= 0; i
< 31; i
++)
2597 current_cpu
->thread_data
[threadno
]
2598 .sigdata
[i
+ 33].blocked_suspendsave
2599 = current_cpu
->thread_data
[threadno
]
2600 .sigdata
[i
+ 33].blocked
;
2601 current_cpu
->thread_data
[threadno
]
2602 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2605 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2607 /* The mask changed, so a signal may be unblocked for
2609 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2612 /* Because we don't use arg1 (newsetp) when this syscall is
2613 rerun, it doesn't matter that we overwrite it with the
2614 (constant) return value. */
2615 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2616 sim_pc_set (current_cpu
, pc
);
2620 /* Add case labels here for other syscalls using the 32-bit
2621 "struct stat", provided they have a corresponding simulator
2622 function of course. */
2623 case TARGET_SYS_stat
:
2624 case TARGET_SYS_fstat
:
2626 /* As long as the infrastructure doesn't cache anything
2627 related to the stat mapping, this trick gets us a dual
2628 "struct stat"-type mapping in the least error-prone way. */
2629 const char *saved_map
= cb
->stat_map
;
2630 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2632 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2633 cb
->stat_map
= stat32_map
;
2635 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2638 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2641 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2643 cb
->stat_map
= saved_map
;
2644 cb
->syscall_map
= saved_syscall_map
;
2648 case TARGET_SYS_getcwd
:
2653 char *cwd
= xmalloc (SIM_PATHMAX
);
2654 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2657 /* FIXME: When and if we support chdir, we need something
2658 a bit more elaborate. */
2659 if (simulator_sysroot
[0] != '\0')
2662 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2663 if (strlen (cwd
) + 1 <= size
)
2665 retval
= strlen (cwd
) + 1;
2666 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2668 != (unsigned int) retval
)
2669 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2675 case TARGET_SYS_access
:
2679 char *pbuf
= xmalloc (SIM_PATHMAX
);
2684 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2686 strcpy (pbuf
, simulator_sysroot
);
2687 o
+= strlen (simulator_sysroot
);
2690 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2693 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2694 if (pbuf
[i
+ o
] == 0)
2698 if (i
+ o
== SIM_PATHMAX
)
2700 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2704 /* Assert that we don't get calls for files for which we
2705 don't have support. */
2706 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2709 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2716 if (access (pbuf
, hmode
) != 0)
2717 retval
= -cb_host_to_target_errno (cb
, errno
);
2725 case TARGET_SYS_readlink
:
2730 char *pbuf
= xmalloc (SIM_PATHMAX
);
2731 char *lbuf
= xmalloc (SIM_PATHMAX
);
2732 char *lbuf_alloc
= lbuf
;
2737 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2739 strcpy (pbuf
, simulator_sysroot
);
2740 o
+= strlen (simulator_sysroot
);
2743 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2746 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2747 if (pbuf
[i
+ o
] == 0)
2751 if (i
+ o
== SIM_PATHMAX
)
2753 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2757 /* Intervene calls for certain files expected in the target
2758 proc file system. */
2759 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2760 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2763 = (STATE_PROG_ARGV (sd
) != NULL
2764 ? *STATE_PROG_ARGV (sd
) : NULL
);
2766 if (argv0
== NULL
|| *argv0
== '.')
2769 = cris_unknown_syscall (current_cpu
, pc
,
2770 "Unimplemented readlink syscall "
2771 "(0x%lx: [\"%s\"], 0x%lx)\n",
2772 (unsigned long) arg1
, pbuf
,
2773 (unsigned long) arg2
);
2776 else if (*argv0
== '/')
2778 if (strncmp (simulator_sysroot
, argv0
,
2779 strlen (simulator_sysroot
)) == 0)
2780 argv0
+= strlen (simulator_sysroot
);
2782 strcpy (lbuf
, argv0
);
2783 nchars
= strlen (argv0
) + 1;
2787 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2788 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2790 if (strncmp (simulator_sysroot
, lbuf
,
2791 strlen (simulator_sysroot
)) == 0)
2792 lbuf
+= strlen (simulator_sysroot
);
2795 strcat (lbuf
, argv0
);
2796 nchars
= strlen (lbuf
) + 1;
2803 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2805 /* We trust that the readlink result returns a *relative*
2806 link, or one already adjusted for the file-path-prefix.
2807 (We can't generally tell the difference, so we go with
2808 the easiest decision; no adjustment.) */
2812 retval
= -cb_host_to_target_errno (cb
, errno
);
2816 if (bufsiz
< nchars
)
2819 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2820 buf
, nchars
) != (unsigned int) nchars
)
2821 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2830 case TARGET_SYS_sched_getscheduler
:
2834 /* FIXME: Search (other) existing threads. */
2835 if (pid
!= 0 && pid
!= TARGET_PID
)
2836 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2838 retval
= TARGET_SCHED_OTHER
;
2842 case TARGET_SYS_sched_getparam
:
2848 struct sched_param {
2852 if (pid
!= 0 && pid
!= TARGET_PID
)
2853 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2856 /* FIXME: Save scheduler setting before threads are
2858 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2859 current_cpu
->thread_data
!= NULL
2861 ->thread_data
[threadno
]
2869 case TARGET_SYS_sched_setparam
:
2874 if ((pid
!= 0 && pid
!= TARGET_PID
)
2875 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2877 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2883 case TARGET_SYS_sched_setscheduler
:
2889 if ((pid
!= 0 && pid
!= TARGET_PID
)
2890 || policy
!= TARGET_SCHED_OTHER
2891 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2893 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2895 /* FIXME: Save scheduler setting to be read in later
2896 sched_getparam calls. */
2901 case TARGET_SYS_sched_yield
:
2902 /* We reschedule to the next thread after a syscall anyway, so
2903 we don't have to do anything here than to set the return
2908 case TARGET_SYS_sched_get_priority_min
:
2909 case TARGET_SYS_sched_get_priority_max
:
2911 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2916 case TARGET_SYS_ugetrlimit
:
2918 unsigned int curlim
, maxlim
;
2919 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2921 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2927 unsigned long rlim_cur;
2928 unsigned long rlim_max;
2930 if (arg1
== TARGET_RLIMIT_NOFILE
)
2932 /* Sadly a very low limit. Better not lie, though. */
2933 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2935 else /* arg1 == TARGET_RLIMIT_STACK */
2937 maxlim
= 0xffffffff;
2940 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2941 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2946 case TARGET_SYS_setrlimit
:
2947 if (arg1
!= TARGET_RLIMIT_STACK
)
2949 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2952 /* FIXME: Save values for future ugetrlimit calls. */
2956 /* Provide a very limited subset of the sysctl functions, and
2957 abort for the rest. */
2958 case TARGET_SYS__sysctl
:
2961 struct __sysctl_args {
2968 unsigned long __unused[4];
2970 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2971 SI name0
= name
== 0
2972 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2973 SI name1
= name
== 0
2974 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2976 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2978 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2980 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2981 SI oldlen
= oldlenp
== 0
2982 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2984 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2986 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2988 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2990 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2991 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2993 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
2994 sizeof (TARGET_UTSNAME
));
2996 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
2997 TARGET_UTSNAME
, oldval
,
2999 != (unsigned int) to_write
)
3000 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
3007 = cris_unknown_syscall (current_cpu
, pc
,
3008 "Unimplemented _sysctl syscall "
3009 "(0x%lx: [0x%lx, 0x%lx],"
3010 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3011 (unsigned long) name
,
3012 (unsigned long) name0
,
3013 (unsigned long) name1
,
3014 (unsigned long) nlen
,
3015 (unsigned long) oldval
,
3016 (unsigned long) oldlenp
,
3017 (unsigned long) newval
,
3018 (unsigned long) newlen
);
3022 case TARGET_SYS_exit
:
3024 /* Here for all but the last thread. */
3027 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3029 = (current_cpu
->thread_data
[threadno
].parent_threadid
3031 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3033 /* Any children are now all orphans. */
3034 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3035 if (current_cpu
->thread_data
[i
].parent_threadid
3036 == current_cpu
->thread_data
[threadno
].threadid
)
3037 /* Make getppid(2) return 1 for them, poor little ones. */
3038 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3040 /* Free the cpu context data. When the parent has received
3041 the exit status, we'll clear the entry too. */
3042 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3043 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3044 current_cpu
->m1threads
--;
3047 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3049 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3053 /* Still, we may want to support non-zero exit values. */
3054 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3057 deliver_signal (current_cpu
, exitsig
, ppid
);
3061 case TARGET_SYS_clone
:
3063 int nthreads
= current_cpu
->m1threads
+ 1;
3064 void *thread_cpu_data
;
3065 bfd_byte old_sp_buf
[4];
3067 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3070 /* That's right, the syscall clone arguments are reversed
3071 compared to sys_clone notes in clone(2) and compared to
3072 other Linux ports (i.e. it's the same order as in the
3073 clone(2) libcall). */
3077 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3079 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3083 /* FIXME: Implement the low byte. */
3084 if ((flags
& ~TARGET_CSIGNAL
) !=
3087 | TARGET_CLONE_FILES
3088 | TARGET_CLONE_SIGHAND
)
3092 = cris_unknown_syscall (current_cpu
, pc
,
3093 "Unimplemented clone syscall "
3095 (unsigned long) arg1
,
3096 (unsigned long) arg2
);
3100 if (current_cpu
->thread_data
== NULL
)
3101 make_first_thread (current_cpu
);
3103 /* The created thread will get the new SP and a cleared R10.
3104 Since it's created out of a copy of the old thread and we
3105 don't have a set-register-function that just take the
3106 cpu_data as a parameter, we set the childs values first,
3107 and write back or overwrite them in the parent after the
3109 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3110 H_GR_SP
, old_sp_buf
, 4);
3111 bfd_putl32 (newsp
, sp_buf
);
3112 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3113 H_GR_SP
, sp_buf
, 4);
3114 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3115 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3118 ->make_thread_cpu_data
) (current_cpu
,
3119 ¤t_cpu
->cpu_data_placeholder
);
3120 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3121 H_GR_SP
, old_sp_buf
, 4);
3123 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3125 /* Find an unused slot. After a few threads have been created
3126 and exited, the array is expected to be a bit fragmented.
3127 We don't reuse the first entry, though, that of the
3129 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3130 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3131 /* Don't reuse a zombied entry. */
3132 && current_cpu
->thread_data
[i
].threadid
== 0)
3135 memcpy (¤t_cpu
->thread_data
[i
],
3136 ¤t_cpu
->thread_data
[threadno
],
3137 sizeof (current_cpu
->thread_data
[i
]));
3138 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3139 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3140 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3141 current_cpu
->thread_data
[i
].parent_threadid
3142 = current_cpu
->thread_data
[threadno
].threadid
;
3143 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3144 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3145 current_cpu
->thread_data
[i
].at_syscall
= 0;
3146 current_cpu
->thread_data
[i
].sigpending
= 0;
3147 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3148 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3149 current_cpu
->m1threads
= nthreads
;
3153 /* Better watch these in case they do something necessary. */
3154 case TARGET_SYS_socketcall
:
3155 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3158 case TARGET_SYS_set_thread_area
:
3159 /* Do the same error check as Linux. */
3162 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
3165 (*current_cpu
->set_target_thread_data
) (current_cpu
, arg1
);
3169 unimplemented_syscall
:
3172 = cris_unknown_syscall (current_cpu
, pc
,
3173 "Unimplemented syscall: %d "
3174 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3175 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3180 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3181 if (callnum
== TARGET_SYS_open
)
3183 current_cpu
->last_open_fd
= retval
;
3184 current_cpu
->last_open_flags
= arg2
;
3187 current_cpu
->last_syscall
= callnum
;
3189 /* A system call is a rescheduling point. For the time being, we don't
3190 reschedule anywhere else. */
3191 if (current_cpu
->m1threads
!= 0
3192 /* We need to schedule off from an exiting thread that is the
3194 || (current_cpu
->thread_data
!= NULL
3195 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3197 bfd_byte retval_buf
[4];
3199 current_cpu
->thread_data
[threadno
].last_execution
3200 = TARGET_TIME_MS (current_cpu
);
3201 bfd_putl32 (retval
, retval_buf
);
3202 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3204 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3205 reschedule (current_cpu
);
3207 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3208 retval
= bfd_getl32 (retval_buf
);
3214 /* Callback from simulator write saying that the pipe at (reader, writer)
3215 is now non-empty (so the writer should wait until the pipe is empty, at
3216 least not write to this or any other pipe). Simplest is to just wait
3217 until the pipe is empty. */
3220 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3221 int reader
, int writer
)
3223 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3224 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3226 /* It's the current thread: we just have to re-run the current
3227 syscall instruction (presumably "break 13") and change the syscall
3228 to the special simulator-wait code. Oh, and set a marker that
3229 we're waiting, so we can disambiguate the special call from a
3232 This function may be called multiple times between cris_pipe_empty,
3233 but we must avoid e.g. decreasing PC every time. Check fd markers
3235 if (cpu
->thread_data
== NULL
)
3237 sim_io_eprintf (CPU_STATE (cpu
),
3238 "Terminating simulation due to writing pipe rd:wr %d:%d"
3239 " from one single thread\n", reader
, writer
);
3240 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3241 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3243 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3245 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3246 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3247 /* FIXME: We really shouldn't change registers other than R10 in
3248 syscalls (like R9), here or elsewhere. */
3249 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3250 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3254 /* Callback from simulator close or read call saying that the pipe at
3255 (reader, writer) is now empty (so the writer can write again, perhaps
3256 leave a waiting state). If there are bytes remaining, they couldn't be
3257 consumed (perhaps due to the pipe closing). */
3260 cris_pipe_empty (host_callback
*cb
,
3265 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3266 bfd_byte r10_buf
[4];
3268 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3270 /* We need to find the thread that waits for this pipe. */
3271 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3272 if (cpu
->thread_data
[i
].cpu_context
3273 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3277 /* Temporarily switch to this cpu context, so we can change the
3278 PC by ordinary calls. */
3280 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3281 &cpu
->cpu_data_placeholder
,
3282 cpu
->thread_cpu_data_size
);
3283 memcpy (&cpu
->cpu_data_placeholder
,
3284 cpu
->thread_data
[i
].cpu_context
,
3285 cpu
->thread_cpu_data_size
);
3287 /* The return value is supposed to contain the number of
3288 written bytes, which is the number of bytes requested and
3289 returned at the write call. You might think the right
3290 thing is to adjust the return-value to be only the
3291 *consumed* number of bytes, but it isn't. We're only
3292 called if the pipe buffer is fully consumed or it is being
3293 closed, possibly with remaining bytes. For the latter
3294 case, the writer is still supposed to see success for
3295 PIPE_BUF bytes (a constant which we happen to know and is
3296 unlikely to change). The return value may also be a
3297 negative number; an error value. This case is covered
3298 because "remaining" is always >= 0. */
3299 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3300 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3301 if (retval
- remaining
> TARGET_PIPE_BUF
)
3303 bfd_putl32 (retval
- remaining
, r10_buf
);
3304 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3306 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3307 memcpy (cpu
->thread_data
[i
].cpu_context
,
3308 &cpu
->cpu_data_placeholder
,
3309 cpu
->thread_cpu_data_size
);
3310 memcpy (&cpu
->cpu_data_placeholder
,
3311 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3312 cpu
->thread_cpu_data_size
);
3313 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3314 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3321 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3324 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
3326 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
3332 /* Set target-specific callback data. */
3335 cris_set_callbacks (host_callback
*cb
)
3337 /* Yeargh, have to cast away constness to avoid warnings. */
3338 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3339 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3341 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3342 parameter to cb_store_target_endian will make st_size negative.
3343 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3344 *unsigned*, and/or add syntax for signed-ness. */
3345 cb
->stat_map
= stat_map
;
3346 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3347 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3348 cb
->pipe_empty
= cris_pipe_empty
;
3349 cb
->time
= cris_time
;
3352 /* Process an address exception. */
3355 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3356 unsigned int map
, int nr_bytes
, address_word addr
,
3357 transfer_type transfer
, sim_core_signals sig
)
3359 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,