1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
3 Contributed by Axis Communications.
5 This file is part of the GNU simulators.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "sim-options.h"
23 /* FIXME: get rid of targ-vals.h usage everywhere else. */
35 #ifdef HAVE_SYS_PARAM_H
36 #include <sys/param.h>
38 #ifdef HAVE_SYS_STAT_H
41 /* For PATH_MAX, originally. */
46 /* From ld/sysdep.h. */
48 # define SIM_PATHMAX PATH_MAX
51 # define SIM_PATHMAX MAXPATHLEN
53 # define SIM_PATHMAX 1024
57 /* The verbatim values are from asm-cris/unistd.h. */
59 #define TARGET_SYS_exit 1
60 #define TARGET_SYS_read 3
61 #define TARGET_SYS_write 4
62 #define TARGET_SYS_open 5
63 #define TARGET_SYS_close 6
64 #define TARGET_SYS_unlink 10
65 #define TARGET_SYS_time 13
66 #define TARGET_SYS_lseek 19
67 #define TARGET_SYS_getpid 20
68 #define TARGET_SYS_access 33
69 #define TARGET_SYS_kill 37
70 #define TARGET_SYS_rename 38
71 #define TARGET_SYS_pipe 42
72 #define TARGET_SYS_brk 45
73 #define TARGET_SYS_ioctl 54
74 #define TARGET_SYS_fcntl 55
75 #define TARGET_SYS_getppid 64
76 #define TARGET_SYS_setrlimit 75
77 #define TARGET_SYS_gettimeofday 78
78 #define TARGET_SYS_readlink 85
79 #define TARGET_SYS_munmap 91
80 #define TARGET_SYS_truncate 92
81 #define TARGET_SYS_ftruncate 93
82 #define TARGET_SYS_socketcall 102
83 #define TARGET_SYS_stat 106
84 #define TARGET_SYS_fstat 108
85 #define TARGET_SYS_wait4 114
86 #define TARGET_SYS_sigreturn 119
87 #define TARGET_SYS_clone 120
88 #define TARGET_SYS_uname 122
89 #define TARGET_SYS_mprotect 125
90 #define TARGET_SYS_llseek 140
91 #define TARGET_SYS_writev 146
92 #define TARGET_SYS__sysctl 149
93 #define TARGET_SYS_sched_setparam 154
94 #define TARGET_SYS_sched_getparam 155
95 #define TARGET_SYS_sched_setscheduler 156
96 #define TARGET_SYS_sched_getscheduler 157
97 #define TARGET_SYS_sched_yield 158
98 #define TARGET_SYS_sched_get_priority_max 159
99 #define TARGET_SYS_sched_get_priority_min 160
100 #define TARGET_SYS_mremap 163
101 #define TARGET_SYS_poll 168
102 #define TARGET_SYS_rt_sigaction 174
103 #define TARGET_SYS_rt_sigprocmask 175
104 #define TARGET_SYS_rt_sigsuspend 179
105 #define TARGET_SYS_getcwd 183
106 #define TARGET_SYS_ugetrlimit 191
107 #define TARGET_SYS_mmap2 192
108 #define TARGET_SYS_stat64 195
109 #define TARGET_SYS_lstat64 196
110 #define TARGET_SYS_fstat64 197
111 #define TARGET_SYS_geteuid32 201
112 #define TARGET_SYS_getuid32 199
113 #define TARGET_SYS_getegid32 202
114 #define TARGET_SYS_getgid32 200
115 #define TARGET_SYS_fcntl64 221
117 #define TARGET_PROT_READ 0x1
118 #define TARGET_PROT_WRITE 0x2
119 #define TARGET_PROT_EXEC 0x4
120 #define TARGET_PROT_NONE 0x0
122 #define TARGET_MAP_SHARED 0x01
123 #define TARGET_MAP_PRIVATE 0x02
124 #define TARGET_MAP_TYPE 0x0f
125 #define TARGET_MAP_FIXED 0x10
126 #define TARGET_MAP_ANONYMOUS 0x20
128 #define TARGET_CTL_KERN 1
129 #define TARGET_CTL_VM 2
130 #define TARGET_CTL_NET 3
131 #define TARGET_CTL_PROC 4
132 #define TARGET_CTL_FS 5
133 #define TARGET_CTL_DEBUG 6
134 #define TARGET_CTL_DEV 7
135 #define TARGET_CTL_BUS 8
136 #define TARGET_CTL_ABI 9
138 #define TARGET_CTL_KERN_VERSION 4
141 #define TARGET_MREMAP_MAYMOVE 1
142 #define TARGET_MREMAP_FIXED 2
144 #define TARGET_TCGETS 0x5401
146 #define TARGET_UTSNAME "#38 Sun Apr 1 00:00:00 MET 2001"
148 /* Seconds since the above date + 10 minutes. */
149 #define TARGET_EPOCH 986080200
151 /* Milliseconds since start of run. We use the number of syscalls to
152 avoid introducing noise in the execution time. */
153 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
155 /* Seconds as in time(2). */
156 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
158 #define TARGET_SCHED_OTHER 0
160 #define TARGET_RLIMIT_STACK 3
161 #define TARGET_RLIMIT_NOFILE 7
163 #define SIM_TARGET_MAX_THREADS 64
164 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
166 /* From linux/sched.h. */
167 #define TARGET_CSIGNAL 0x000000ff
168 #define TARGET_CLONE_VM 0x00000100
169 #define TARGET_CLONE_FS 0x00000200
170 #define TARGET_CLONE_FILES 0x00000400
171 #define TARGET_CLONE_SIGHAND 0x00000800
172 #define TARGET_CLONE_PID 0x00001000
173 #define TARGET_CLONE_PTRACE 0x00002000
174 #define TARGET_CLONE_VFORK 0x00004000
175 #define TARGET_CLONE_PARENT 0x00008000
176 #define TARGET_CLONE_THREAD 0x00010000
177 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
179 /* From asm-cris/poll.h. */
180 #define TARGET_POLLIN 1
182 /* From asm-cris/signal.h. */
183 #define TARGET_SIG_BLOCK 0
184 #define TARGET_SIG_UNBLOCK 1
185 #define TARGET_SIG_SETMASK 2
187 #define TARGET_SIG_DFL 0
188 #define TARGET_SIG_IGN 1
189 #define TARGET_SIG_ERR ((USI)-1)
191 #define TARGET_SIGHUP 1
192 #define TARGET_SIGINT 2
193 #define TARGET_SIGQUIT 3
194 #define TARGET_SIGILL 4
195 #define TARGET_SIGTRAP 5
196 #define TARGET_SIGABRT 6
197 #define TARGET_SIGIOT 6
198 #define TARGET_SIGBUS 7
199 #define TARGET_SIGFPE 8
200 #define TARGET_SIGKILL 9
201 #define TARGET_SIGUSR1 10
202 #define TARGET_SIGSEGV 11
203 #define TARGET_SIGUSR2 12
204 #define TARGET_SIGPIPE 13
205 #define TARGET_SIGALRM 14
206 #define TARGET_SIGTERM 15
207 #define TARGET_SIGSTKFLT 16
208 #define TARGET_SIGCHLD 17
209 #define TARGET_SIGCONT 18
210 #define TARGET_SIGSTOP 19
211 #define TARGET_SIGTSTP 20
212 #define TARGET_SIGTTIN 21
213 #define TARGET_SIGTTOU 22
214 #define TARGET_SIGURG 23
215 #define TARGET_SIGXCPU 24
216 #define TARGET_SIGXFSZ 25
217 #define TARGET_SIGVTALRM 26
218 #define TARGET_SIGPROF 27
219 #define TARGET_SIGWINCH 28
220 #define TARGET_SIGIO 29
221 #define TARGET_SIGPOLL SIGIO
222 /* Actually commented out in the kernel header. */
223 #define TARGET_SIGLOST 29
224 #define TARGET_SIGPWR 30
225 #define TARGET_SIGSYS 31
227 /* From include/asm-cris/signal.h. */
228 #define TARGET_SA_NOCLDSTOP 0x00000001
229 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
230 #define TARGET_SA_SIGINFO 0x00000004
231 #define TARGET_SA_ONSTACK 0x08000000
232 #define TARGET_SA_RESTART 0x10000000
233 #define TARGET_SA_NODEFER 0x40000000
234 #define TARGET_SA_RESETHAND 0x80000000
235 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
236 #define TARGET_SA_RESTORER 0x04000000
238 /* From linux/wait.h. */
239 #define TARGET_WNOHANG 1
240 #define TARGET_WUNTRACED 2
241 #define TARGET___WNOTHREAD 0x20000000
242 #define TARGET___WALL 0x40000000
243 #define TARGET___WCLONE 0x80000000
245 /* From linux/limits.h. */
246 #define TARGET_PIPE_BUF 4096
249 #define TARGET_R_OK 4
250 #define TARGET_W_OK 2
251 #define TARGET_X_OK 1
252 #define TARGET_F_OK 0
254 static const char stat_map
[] =
255 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
256 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
257 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
260 static const CB_TARGET_DEFS_MAP syscall_map
[] =
262 { CB_SYS_open
, TARGET_SYS_open
},
263 { CB_SYS_close
, TARGET_SYS_close
},
264 { CB_SYS_read
, TARGET_SYS_read
},
265 { CB_SYS_write
, TARGET_SYS_write
},
266 { CB_SYS_lseek
, TARGET_SYS_lseek
},
267 { CB_SYS_unlink
, TARGET_SYS_unlink
},
268 { CB_SYS_getpid
, TARGET_SYS_getpid
},
269 { CB_SYS_fstat
, TARGET_SYS_fstat64
},
270 { CB_SYS_lstat
, TARGET_SYS_lstat64
},
271 { CB_SYS_stat
, TARGET_SYS_stat64
},
272 { CB_SYS_pipe
, TARGET_SYS_pipe
},
273 { CB_SYS_rename
, TARGET_SYS_rename
},
274 { CB_SYS_truncate
, TARGET_SYS_truncate
},
275 { CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
279 /* An older, 32-bit-only stat mapping. */
280 static const char stat32_map
[] =
281 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
282 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
283 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
285 /* Map for calls using the 32-bit struct stat. Primarily used by the
286 newlib Linux mapping. */
287 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
289 { CB_SYS_fstat
, TARGET_SYS_fstat
},
290 { CB_SYS_stat
, TARGET_SYS_stat
},
294 /* Giving the true value for the running sim process will lead to
295 non-time-invariant behavior. */
296 #define TARGET_PID 42
298 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
299 we did, we'd still don't get a register number with the "16" offset. */
300 #define TARGET_SRP_REGNUM (16+11)
302 /* Extracted by applying
303 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
304 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
305 adjusting the synonyms. */
307 static const CB_TARGET_DEFS_MAP errno_map
[] =
415 { ENAMETOOLONG
, 36 },
574 { EDESTADDRREQ
, 89 },
585 #ifdef EPROTONOSUPPORT
586 { EPROTONOSUPPORT
, 93 },
588 #ifdef ESOCKTNOSUPPORT
589 { ESOCKTNOSUPPORT
, 94 },
595 { EPFNOSUPPORT
, 96 },
598 { EAFNOSUPPORT
, 97 },
604 { EADDRNOTAVAIL
, 99 },
610 { ENETUNREACH
, 101 },
616 { ECONNABORTED
, 103 },
634 { ETOOMANYREFS
, 109 },
640 { ECONNREFUSED
, 111 },
646 { EHOSTUNREACH
, 113 },
652 { EINPROGRESS
, 115 },
679 { EMEDIUMTYPE
, 124 },
684 /* Extracted by applying
685 perl -ne 'if ($_ =~ /^#define/) { split;
686 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
687 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
688 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
689 installation and removing synonyms and unnecessary items. Don't
690 forget the end-marker. */
692 /* These we treat specially, as they're used in the fcntl F_GETFL
693 syscall. For consistency, open_map is also manually edited to use
695 #define TARGET_O_ACCMODE 0x3
696 #define TARGET_O_RDONLY 0x0
697 #define TARGET_O_WRONLY 0x1
699 static const CB_TARGET_DEFS_MAP open_map
[] = {
701 { O_ACCMODE
, TARGET_O_ACCMODE
},
704 { O_RDONLY
, TARGET_O_RDONLY
},
707 { O_WRONLY
, TARGET_O_WRONLY
},
728 { O_NONBLOCK
, 0x800 },
740 { O_DIRECT
, 0x4000 },
743 { O_LARGEFILE
, 0x8000 },
746 { O_DIRECTORY
, 0x10000 },
749 { O_NOFOLLOW
, 0x20000 },
754 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
755 static SIM_CPU
*current_cpu_for_cb_callback
;
757 static int syscall_read_mem (host_callback
*, struct cb_syscall
*,
758 unsigned long, char *, int);
759 static int syscall_write_mem (host_callback
*, struct cb_syscall
*,
760 unsigned long, const char *, int);
761 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
763 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
765 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
767 static void dump_statistics (SIM_CPU
*current_cpu
);
768 static void make_first_thread (SIM_CPU
*current_cpu
);
770 /* Read/write functions for system call interface. */
773 syscall_read_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
774 struct cb_syscall
*sc
,
775 unsigned long taddr
, char *buf
, int bytes
)
777 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
778 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
780 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
784 syscall_write_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
785 struct cb_syscall
*sc
,
786 unsigned long taddr
, const char *buf
, int bytes
)
788 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
789 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
791 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
794 /* When we risk running self-modified code (as in trampolines), this is
795 called from special-case insns. The silicon CRIS CPU:s have enough
796 cache snooping implemented making this a simulator-only issue. Tests:
797 gcc.c-torture/execute/931002-1.c execution, -O3 -g
798 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
801 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
802 USI pc ATTRIBUTE_UNUSED
)
804 SIM_DESC sd
= CPU_STATE (current_cpu
);
807 if (USING_SCACHE_P (sd
))
808 scache_flush_cpu (current_cpu
);
812 /* Output statistics at the end of a run. */
814 dump_statistics (SIM_CPU
*current_cpu
)
816 SIM_DESC sd
= CPU_STATE (current_cpu
);
817 CRIS_MISC_PROFILE
*profp
818 = CPU_CRIS_MISC_PROFILE (current_cpu
);
819 unsigned64 total
= profp
->basic_cycle_count
;
820 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
822 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
823 what's included in the "total" count only. */
824 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
825 & FLAG_CRIS_MISC_PROFILE_ALL
)
827 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
830 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
832 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
833 total
+= profp
->unaligned_mem_dword_count
;
836 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
837 textmsg
= "Schedulable clock cycles, total @: %llu\n";
839 += (profp
->memsrc_stall_count
840 + profp
->memraw_stall_count
841 + profp
->movemsrc_stall_count
842 + profp
->movemdst_stall_count
843 + profp
->mulsrc_stall_count
844 + profp
->jumpsrc_stall_count
845 + profp
->unaligned_mem_dword_count
);
848 case FLAG_CRIS_MISC_PROFILE_ALL
:
849 textmsg
= "All accounted clock cycles, total @: %llu\n";
851 += (profp
->memsrc_stall_count
852 + profp
->memraw_stall_count
853 + profp
->movemsrc_stall_count
854 + profp
->movemdst_stall_count
855 + profp
->movemaddr_stall_count
856 + profp
->mulsrc_stall_count
857 + profp
->jumpsrc_stall_count
858 + profp
->branch_stall_count
859 + profp
->jumptarget_stall_count
860 + profp
->unaligned_mem_dword_count
);
867 "Internal inconsistency at %s:%d",
869 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
870 sim_stopped
, SIM_SIGILL
);
873 /* Historically, these messages have gone to stderr, so we'll keep it
874 that way. It's also easier to then tell it from normal program
875 output. FIXME: Add redirect option like "run -e file". */
876 sim_io_eprintf (sd
, textmsg
, total
);
878 /* For v32, unaligned_mem_dword_count should always be 0. For
879 v10, memsrc_stall_count should always be 0. */
880 sim_io_eprintf (sd
, "Memory source stall cycles: %llu\n",
881 (unsigned long long) (profp
->memsrc_stall_count
882 + profp
->unaligned_mem_dword_count
));
883 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %llu\n",
884 (unsigned long long) profp
->memraw_stall_count
);
885 sim_io_eprintf (sd
, "Movem source stall cycles: %llu\n",
886 (unsigned long long) profp
->movemsrc_stall_count
);
887 sim_io_eprintf (sd
, "Movem destination stall cycles: %llu\n",
888 (unsigned long long) profp
->movemdst_stall_count
);
889 sim_io_eprintf (sd
, "Movem address stall cycles: %llu\n",
890 (unsigned long long) profp
->movemaddr_stall_count
);
891 sim_io_eprintf (sd
, "Multiplication source stall cycles: %llu\n",
892 (unsigned long long) profp
->mulsrc_stall_count
);
893 sim_io_eprintf (sd
, "Jump source stall cycles: %llu\n",
894 (unsigned long long) profp
->jumpsrc_stall_count
);
895 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %llu\n",
896 (unsigned long long) profp
->branch_stall_count
);
897 sim_io_eprintf (sd
, "Jump target stall cycles: %llu\n",
898 (unsigned long long) profp
->jumptarget_stall_count
);
901 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
902 Return 1 if a overlap detected, 0 otherwise. */
905 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
906 struct cris_sim_mmapped_page
**rootp
,
909 struct cris_sim_mmapped_page
*mapp
;
911 if (len
== 0 || (len
& 8191))
914 /* Iterate over the reverse-address sorted pages until we find a page in
915 or lower than the checked area. */
916 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
917 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
923 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
924 Return 1 if the whole area is mapped, 0 otherwise. */
927 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
928 struct cris_sim_mmapped_page
**rootp
,
931 struct cris_sim_mmapped_page
*mapp
;
933 if (len
== 0 || (len
& 8191))
936 /* Iterate over the reverse-address sorted pages until we find a page
937 lower than the checked area. */
938 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
939 if (addr
== mapp
->addr
&& len
== 8192)
941 else if (addr
+ len
> mapp
->addr
)
947 /* Debug helper; to be run from gdb. */
950 cris_dump_map (SIM_CPU
*current_cpu
)
952 struct cris_sim_mmapped_page
*mapp
;
955 for (mapp
= current_cpu
->highest_mmapped_page
,
956 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
957 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
961 if (mapp
->addr
!= start
- 8192)
963 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
964 end
= mapp
->addr
+ 8191;
970 if (current_cpu
->highest_mmapped_page
!= NULL
)
971 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
974 /* Create mmapped memory. */
977 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
980 struct cris_sim_mmapped_page
*mapp
;
981 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
982 USI new_addr
= 0x40000000;
987 new_addr
= rootp
[0]->addr
+ 8192;
994 /* Which is better: return an error for this, or just round it up? */
997 /* Do a recursive call for each page in the request. */
998 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
999 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
1006 mapp
!= NULL
&& mapp
->addr
> new_addr
;
1008 higher_prevp
= &mapp
->prev
;
1010 /* Allocate the new page, on the next higher page from the last one
1011 allocated, and link in the new descriptor before previous ones. */
1012 mapp
= malloc (sizeof (*mapp
));
1015 return (USI
) -ENOMEM
;
1017 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1021 mapp
->addr
= new_addr
;
1022 mapp
->prev
= *higher_prevp
;
1023 *higher_prevp
= mapp
;
1028 /* Unmap one or more pages. */
1031 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1034 struct cris_sim_mmapped_page
*mapp
;
1035 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1042 /* Which is better: return an error for this, or just round it up? */
1045 /* Loop backwards to make each call is O(1) over the number of pages
1046 allocated, if we're unmapping from the high end of the pages. */
1047 for (page_addr
= addr
+ len
- 8192;
1050 if (unmap_pages (sd
, rootp
, page_addr
, 8192) != 0)
1056 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1057 higher_prevp
= &mapp
->prev
;
1059 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1062 *higher_prevp
= mapp
->prev
;
1063 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1068 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1071 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1073 SIM_DESC sd
= CPU_STATE (current_cpu
);
1075 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1079 /* Handlers from the CGEN description that should not be called. */
1082 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1083 UINT srcreg ATTRIBUTE_UNUSED
,
1084 USI dstreg ATTRIBUTE_UNUSED
)
1090 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1091 UINT index ATTRIBUTE_UNUSED
,
1092 USI page ATTRIBUTE_UNUSED
,
1093 USI newval ATTRIBUTE_UNUSED
)
1099 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1100 UINT index ATTRIBUTE_UNUSED
,
1101 USI page ATTRIBUTE_UNUSED
)
1106 /* Swap one context for another. */
1109 schedule (SIM_CPU
*current_cpu
, int next
)
1111 /* Need to mark context-switches in the trace output. */
1112 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1113 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1114 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1117 /* Copy the current context (if there is one) to its slot. */
1118 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1119 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1120 ¤t_cpu
->cpu_data_placeholder
,
1121 current_cpu
->thread_cpu_data_size
);
1123 /* Copy the new context from its slot. */
1124 memcpy (¤t_cpu
->cpu_data_placeholder
,
1125 current_cpu
->thread_data
[next
].cpu_context
,
1126 current_cpu
->thread_cpu_data_size
);
1128 /* Update needed stuff to indicate the new context. */
1129 current_cpu
->threadno
= next
;
1131 /* Handle pending signals. */
1132 if (current_cpu
->thread_data
[next
].sigpending
1133 /* We don't run nested signal handlers. This means that pause(2)
1134 and sigsuspend(2) do not work in sighandlers, but that
1135 shouldn't be too hard a restriction. It also greatly
1136 simplifies the code. */
1137 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1141 /* See if there's really a pending, non-blocked handler. We don't
1142 queue signals, so just use the first one in ascending order. */
1143 for (sig
= 0; sig
< 64; sig
++)
1144 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1145 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1151 USI pc
= sim_pc_get (current_cpu
);
1153 /* It's simpler to save the CPU context inside the simulator
1154 than on the stack. */
1155 current_cpu
->thread_data
[next
].cpu_context_atsignal
1157 ->make_thread_cpu_data
) (current_cpu
,
1158 current_cpu
->thread_data
[next
]
1161 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1162 sp
= bfd_getl32 (regbuf
);
1164 /* Make sure we have an aligned stack. */
1167 /* Make room for the signal frame, aligned. FIXME: Check that
1168 the memory exists, map it in if absent. (BTW, should also
1169 implement on-access automatic stack allocation). */
1172 /* This isn't the same signal frame as the kernel uses, because
1173 we don't want to bother getting all registers on and off the
1176 /* First, we store the currently blocked signals. */
1178 for (i
= 0; i
< 32; i
++)
1180 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1181 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1183 for (i
= 0; i
< 31; i
++)
1185 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1186 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1188 /* Then, the actual instructions. This is CPU-specific, but we
1189 use instructions from the common subset for v10 and v32 which
1190 should be safe for the time being but could be parametrized
1192 /* MOVU.W [PC+],R9. */
1193 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1194 /* .WORD TARGET_SYS_sigreturn. */
1195 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1196 TARGET_SYS_sigreturn
);
1198 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1200 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1201 instruction. Still, it doesn't matter because v10 has no
1202 delay slot for BREAK so it will not be executed). */
1203 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1205 /* Modify registers to hold the right values for the sighandler
1206 context: updated stackpointer and return address pointing to
1207 the sigreturn stub. */
1208 bfd_putl32 (sp
, regbuf
);
1209 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1210 bfd_putl32 (sp
+ 8, regbuf
);
1211 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1214 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1216 /* Block this signal (for the duration of the sighandler). */
1217 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1219 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1220 bfd_putl32 (sig
, regbuf
);
1221 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1224 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1225 needed all this for, specifies a SA_SIGINFO call but treats it
1226 like an ordinary sighandler; only the signal number argument is
1227 inspected. To make future need to implement SA_SIGINFO
1228 correctly possible, we set the siginfo argument register to a
1229 magic (hopefully non-address) number. (NB: then, you should
1230 just need to pass the siginfo argument; it seems you probably
1231 don't need to implement the specific rt_sigreturn.) */
1232 bfd_putl32 (0xbad5161f, regbuf
);
1233 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1236 /* The third argument is unused and the kernel sets it to 0. */
1237 bfd_putl32 (0, regbuf
);
1238 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1243 /* No, there actually was no pending signal for this thread. Reset
1245 current_cpu
->thread_data
[next
].sigpending
= 0;
1249 /* Reschedule the simplest possible way until something else is absolutely
1251 - A. Find the next process (round-robin) that doesn't have at_syscall
1253 - B. If there is none, just run the next process, round-robin.
1254 - Clear at_syscall for the current process. */
1257 reschedule (SIM_CPU
*current_cpu
)
1261 /* Iterate over all thread slots, because after a few thread creations
1262 and exits, we don't know where the live ones are. */
1263 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1264 i
!= current_cpu
->threadno
;
1265 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1266 if (current_cpu
->thread_data
[i
].cpu_context
1267 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1269 schedule (current_cpu
, i
);
1273 /* Pick any next live thread. */
1274 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1275 i
!= current_cpu
->threadno
;
1276 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1277 if (current_cpu
->thread_data
[i
].cpu_context
)
1279 schedule (current_cpu
, i
);
1283 /* More than one live thread, but we couldn't find the next one? */
1287 /* Set up everything to receive (or IGN) an incoming signal to the
1291 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1294 USI pc
= sim_pc_get (current_cpu
);
1296 /* Find the thread index of the pid. */
1297 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1298 /* Apparently it's ok to send signals to zombies (so a check for
1299 current_cpu->thread_data[i].cpu_context != NULL would be
1301 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1304 switch (current_cpu
->sighandler
[sig
])
1306 case TARGET_SIG_DFL
:
1309 /* The following according to the glibc
1310 documentation. (The kernel code has non-obvious
1311 execution paths.) */
1314 case TARGET_SIGSEGV
:
1316 case TARGET_SIGABRT
:
1317 case TARGET_SIGTRAP
:
1320 case TARGET_SIGTERM
:
1322 case TARGET_SIGQUIT
:
1323 case TARGET_SIGKILL
:
1326 case TARGET_SIGALRM
:
1327 case TARGET_SIGVTALRM
:
1328 case TARGET_SIGPROF
:
1329 case TARGET_SIGSTOP
:
1331 case TARGET_SIGPIPE
:
1332 case TARGET_SIGLOST
:
1333 case TARGET_SIGXCPU
:
1334 case TARGET_SIGXFSZ
:
1335 case TARGET_SIGUSR1
:
1336 case TARGET_SIGUSR2
:
1337 sim_io_eprintf (CPU_STATE (current_cpu
),
1338 "Exiting pid %d due to signal %d\n",
1340 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1341 NULL
, pc
, sim_stopped
,
1342 sig
== TARGET_SIGABRT
1343 ? SIM_SIGABRT
: SIM_SIGILL
);
1346 /* The default for all other signals is to be ignored. */
1351 case TARGET_SIG_IGN
:
1354 case TARGET_SIGKILL
:
1355 case TARGET_SIGSTOP
:
1356 /* Can't ignore these signals. */
1357 sim_io_eprintf (CPU_STATE (current_cpu
),
1358 "Exiting pid %d due to signal %d\n",
1360 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1361 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1370 /* Mark the signal as pending, making schedule () check
1371 closer. The signal will be handled when the thread is
1372 scheduled and the signal is unblocked. */
1373 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1374 current_cpu
->thread_data
[i
].sigpending
= 1;
1379 sim_io_eprintf (CPU_STATE (current_cpu
),
1380 "Unimplemented signal: %d\n", sig
);
1381 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1382 sim_stopped
, SIM_SIGILL
);
1387 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1391 /* Make the vector and the first item, the main thread. */
1394 make_first_thread (SIM_CPU
*current_cpu
)
1396 current_cpu
->thread_data
1398 SIM_TARGET_MAX_THREADS
1399 * sizeof (current_cpu
->thread_data
[0]));
1400 current_cpu
->thread_data
[0].cpu_context
1401 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1403 ->cpu_data_placeholder
);
1404 current_cpu
->thread_data
[0].parent_threadid
= -1;
1406 /* For good measure. */
1407 if (TARGET_SIG_DFL
!= 0)
1411 /* Handle unknown system calls. Returns (if it does) the syscall
1415 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1417 SIM_DESC sd
= CPU_STATE (current_cpu
);
1418 host_callback
*cb
= STATE_CALLBACK (sd
);
1420 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1421 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1426 sim_io_evprintf (sd
, s
, ap
);
1429 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1430 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1433 return -cb_host_to_target_errno (cb
, ENOSYS
);
1436 /* Main function: the handler of the "break 13" syscall insn. */
1439 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1440 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1444 SIM_DESC sd
= CPU_STATE (current_cpu
);
1445 host_callback
*cb
= STATE_CALLBACK (sd
);
1447 int threadno
= current_cpu
->threadno
;
1449 current_cpu
->syscalls
++;
1451 CB_SYSCALL_INIT (&s
);
1457 if (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0)
1459 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1460 & FLAG_CRIS_MISC_PROFILE_ALL
)
1461 dump_statistics (current_cpu
);
1462 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1466 s
.p2
= (PTR
) current_cpu
;
1467 s
.read_mem
= syscall_read_mem
;
1468 s
.write_mem
= syscall_write_mem
;
1470 current_cpu_for_cb_callback
= current_cpu
;
1472 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1475 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1477 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1480 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1482 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1484 /* If the generic simulator call said ENOSYS, then let's try the
1485 ones we know ourselves.
1487 The convention is to provide *very limited* functionality on an
1488 as-needed basis, only what's covered by the test-suite, tests
1489 added when functionality changes and abort with a descriptive
1490 message for *everything* else. Where there's no test-case, we
1495 /* It's a pretty safe bet that the "old setup() system call"
1496 number will not be re-used; we can't say the same for higher
1497 numbers. We treat this simulator-generated call as "wait
1498 forever"; we re-run this insn. The wait is ended by a
1499 callback. Sanity check that this is the reason we got
1501 if (current_cpu
->thread_data
== NULL
1502 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1503 goto unimplemented_syscall
;
1505 sim_pc_set (current_cpu
, pc
);
1509 case TARGET_SYS_fcntl64
:
1510 case TARGET_SYS_fcntl
:
1515 Glibc checks stdin, stdout and stderr fd:s for
1516 close-on-exec security sanity. We just need to provide a
1517 OK return value. If we really need to have a
1518 close-on-exec flag true, we could just do a real fcntl
1524 /* F_SETFD. Just ignore attempts to set the close-on-exec
1530 /* F_GETFL. Check for the special case for open+fdopen. */
1531 if (current_cpu
->last_syscall
== TARGET_SYS_open
1532 && arg1
== current_cpu
->last_open_fd
)
1534 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1539 /* Because we can't freopen fd:s 0, 1, 2 to mean
1540 something else than stdin, stdout and stderr
1541 (sim/common/syscall.c:cb_syscall special cases fd
1542 0, 1 and 2), we know what flags that we can
1543 sanely return for these fd:s. */
1544 retval
= TARGET_O_RDONLY
;
1547 else if (arg1
== 1 || arg1
== 2)
1549 retval
= TARGET_O_WRONLY
;
1554 /* Nothing else is implemented. */
1556 = cris_unknown_syscall (current_cpu
, pc
,
1557 "Unimplemented %s syscall "
1558 "(fd: 0x%lx: cmd: 0x%lx arg: "
1560 callnum
== TARGET_SYS_fcntl
1561 ? "fcntl" : "fcntl64",
1562 (unsigned long) (USI
) arg1
,
1563 (unsigned long) (USI
) arg2
,
1564 (unsigned long) (USI
) arg3
);
1569 case TARGET_SYS_uname
:
1571 /* Fill in a few constants to appease glibc. */
1572 static const char sim_utsname
[6][65] =
1582 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1583 sizeof (sim_utsname
))
1584 != sizeof (sim_utsname
))
1585 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1591 case TARGET_SYS_geteuid32
:
1592 /* We tell the truth with these. Maybe we shouldn't, but it
1593 should match the "stat" information. */
1594 retval
= geteuid ();
1597 case TARGET_SYS_getuid32
:
1601 case TARGET_SYS_getegid32
:
1602 retval
= getegid ();
1605 case TARGET_SYS_getgid32
:
1609 case TARGET_SYS_brk
:
1610 /* Most often, we just return the argument, like the Linux
1615 retval
= current_cpu
->endbrk
;
1616 else if (arg1
<= current_cpu
->endmem
)
1617 current_cpu
->endbrk
= arg1
;
1620 USI new_end
= (arg1
+ 8191) & ~8191;
1622 /* If the simulator wants to brk more than a certain very
1623 large amount, something is wrong. FIXME: Return an error
1624 or abort? Have command-line selectable? */
1625 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1627 current_cpu
->endbrk
= current_cpu
->endmem
;
1628 retval
= current_cpu
->endmem
;
1632 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1633 current_cpu
->endmem
,
1634 new_end
- current_cpu
->endmem
,
1636 current_cpu
->endbrk
= arg1
;
1637 current_cpu
->endmem
= new_end
;
1641 case TARGET_SYS_getpid
:
1642 /* Correct until CLONE_THREAD is implemented. */
1643 retval
= current_cpu
->thread_data
== NULL
1645 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1648 case TARGET_SYS_getppid
:
1649 /* Correct until CLONE_THREAD is implemented. */
1650 retval
= current_cpu
->thread_data
== NULL
1653 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1656 case TARGET_SYS_mmap2
:
1665 /* If the simulator wants to mmap more than the very large
1666 limit, something is wrong. FIXME: Return an error or
1667 abort? Have command-line selectable? */
1668 if (len
> SIM_MAX_ALLOC_CHUNK
)
1670 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1674 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1676 != (TARGET_PROT_READ
1678 | TARGET_PROT_EXEC
))
1679 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1680 && prot
!= TARGET_PROT_READ
)
1681 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1682 && flags
!= TARGET_MAP_PRIVATE
1683 && flags
!= (TARGET_MAP_ANONYMOUS
1684 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1685 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1686 && flags
!= TARGET_MAP_SHARED
)
1688 && prot
!= TARGET_PROT_READ
1689 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1690 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1691 || (fd
== (USI
) -1 && pgoff
!= 0)
1692 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
))
1693 || ((flags
& TARGET_MAP_FIXED
) == 0
1694 && is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1695 addr
, (len
+ 8191) & ~8191)))
1698 = cris_unknown_syscall (current_cpu
, pc
,
1699 "Unimplemented mmap2 call "
1700 "(0x%lx, 0x%lx, 0x%lx, "
1701 "0x%lx, 0x%lx, 0x%lx)\n",
1702 (unsigned long) arg1
,
1703 (unsigned long) arg2
,
1704 (unsigned long) arg3
,
1705 (unsigned long) arg4
,
1706 (unsigned long) arg5
,
1707 (unsigned long) arg6
);
1710 else if (fd
!= (USI
) -1)
1717 /* A non-aligned argument is allowed for files. */
1718 USI newlen
= (len
+ 8191) & ~8191;
1720 /* We only support read, read|exec, and read|write,
1721 which we should already have checked. Check again
1723 if (prot
!= TARGET_PROT_READ
1724 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1725 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1728 if ((flags
& TARGET_MAP_FIXED
)
1729 && unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1734 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1737 if (newaddr
>= (USI
) -8191)
1740 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1744 /* We were asked for MAP_FIXED, but couldn't. */
1745 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1748 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1750 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1754 /* Find the current position in the file. */
1755 s
.func
= TARGET_SYS_lseek
;
1759 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1766 /* Move to the correct offset in the file. */
1767 s
.func
= TARGET_SYS_lseek
;
1769 s
.arg2
= pgoff
*8192;
1771 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1777 /* Use the standard read callback to read in "len"
1779 s
.func
= TARGET_SYS_read
;
1783 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1786 if ((USI
) s
.result
!= len
)
1789 /* After reading, we need to go back to the previous
1790 position in the file. */
1791 s
.func
= TARGET_SYS_lseek
;
1795 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1797 if (pos
!= (USI
) s
.result
)
1804 USI newlen
= (len
+ 8191) & ~8191;
1807 if ((flags
& TARGET_MAP_FIXED
)
1808 && unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1812 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1815 if (newaddr
>= (USI
) -8191)
1816 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1820 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1823 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1825 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1832 case TARGET_SYS_mprotect
:
1834 /* We only cover the case of linuxthreads mprotecting out
1835 its stack guard page and of dynamic loading mprotecting
1836 away the data (for some reason the whole library, then
1837 mprotects away the data part and mmap-FIX:es it again. */
1842 if (prot
!= TARGET_PROT_NONE
1843 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1844 addr
, (len
+ 8191) & ~8191))
1847 = cris_unknown_syscall (current_cpu
, pc
,
1848 "Unimplemented mprotect call "
1849 "(0x%lx, 0x%lx, 0x%lx)\n",
1850 (unsigned long) arg1
,
1851 (unsigned long) arg2
,
1852 (unsigned long) arg3
);
1856 /* Just ignore this. We could make this equal to munmap,
1857 but then we'd have to make sure no anon mmaps gets this
1858 address before a subsequent MAP_FIXED mmap intended to
1864 case TARGET_SYS_ioctl
:
1866 /* We support only a very limited functionality: checking
1867 stdout with TCGETS to perform the isatty function. The
1868 TCGETS ioctl isn't actually performed or the result used by
1869 an isatty () caller in a "hello, world" program; only the
1870 return value is then used. Maybe we shouldn't care about
1871 the environment of the simulator regarding isatty, but
1872 that's been working before, in the xsim simulator. */
1873 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1874 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1876 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1880 case TARGET_SYS_munmap
:
1885 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1887 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1891 case TARGET_SYS_wait4
:
1899 /* FIXME: We're not properly implementing __WCLONE, and we
1900 don't really need the special casing so we might as well
1901 make this general. */
1902 if ((!(pid
== (USI
) -1
1903 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1906 && (options
== TARGET___WCLONE
1907 || options
== TARGET___WALL
)))
1909 || current_cpu
->thread_data
== NULL
)
1912 = cris_unknown_syscall (current_cpu
, pc
,
1913 "Unimplemented wait4 call "
1914 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1915 (unsigned long) arg1
,
1916 (unsigned long) arg2
,
1917 (unsigned long) arg3
,
1918 (unsigned long) arg4
);
1922 if (pid
== (USI
) -1)
1923 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1925 if (current_cpu
->thread_data
[threadno
].threadid
1926 == current_cpu
->thread_data
[i
].parent_threadid
1927 && current_cpu
->thread_data
[i
].threadid
!= 0
1928 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1930 /* A zombied child. Get the exit value and clear the
1931 zombied entry so it will be reused. */
1932 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1934 ->thread_data
[i
].exitval
);
1936 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1937 memset (¤t_cpu
->thread_data
[i
], 0,
1938 sizeof (current_cpu
->thread_data
[i
]));
1944 /* We're waiting for a specific PID. If we don't find
1945 it zombied on this run, rerun the syscall. */
1946 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1947 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1948 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1951 /* Get the exit value if the caller wants it. */
1952 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1959 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1960 memset (¤t_cpu
->thread_data
[i
], 0,
1961 sizeof (current_cpu
->thread_data
[i
]));
1966 sim_pc_set (current_cpu
, pc
);
1969 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1974 case TARGET_SYS_rt_sigaction
:
1982 __sighandler_t sa_handler;
1983 unsigned long sa_flags;
1984 void (*sa_restorer)(void);
1990 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
1991 current_cpu
->sighandler
[signum
]);
1992 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
1993 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
1995 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
1996 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
1997 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
2001 USI target_sa_handler
2002 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2004 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2005 USI target_sa_restorer
2006 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2007 USI target_sa_mask_low
2008 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2009 USI target_sa_mask_high
2010 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2012 /* We won't interrupt a syscall so we won't restart it,
2013 but a signal(2) call ends up syscalling rt_sigaction
2014 with this flag, so we have to handle it. The
2015 sa_restorer field contains garbage when not
2016 TARGET_SA_RESTORER, so don't look at it. For the
2017 time being, we don't nest sighandlers, so we
2018 ignore the sa_mask, which simplifies things. */
2019 if ((target_sa_flags
!= 0
2020 && target_sa_flags
!= TARGET_SA_RESTART
2021 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2022 || target_sa_handler
== 0)
2025 = cris_unknown_syscall (current_cpu
, pc
,
2026 "Unimplemented rt_sigaction "
2029 "[0x%x, 0x%x, 0x%x, "
2030 "{0x%x, 0x%x}], 0x%lx)\n",
2031 (unsigned long) arg1
,
2032 (unsigned long) arg2
,
2037 target_sa_mask_high
,
2038 (unsigned long) arg3
);
2042 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2044 /* Because we may have unblocked signals, one may now be
2045 pending, if there are threads, that is. */
2046 if (current_cpu
->thread_data
)
2047 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2053 case TARGET_SYS_mremap
:
2059 USI new_addr
= arg5
;
2062 if (new_len
== old_len
)
2063 /* The program and/or library is possibly confused but
2064 this is a valid call. Happens with ipps-1.40 on file
2067 else if (new_len
< old_len
)
2069 /* Shrinking is easy. */
2070 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2071 addr
+ new_len
, old_len
- new_len
) != 0)
2072 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2076 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2077 addr
+ old_len
, new_len
- old_len
))
2079 /* If the extension isn't mapped, we can just add it. */
2081 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2082 addr
+ old_len
, new_len
- old_len
);
2084 if (mapped_addr
> (USI
) -8192)
2085 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2089 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2091 /* Create a whole new map and copy the contents
2092 block-by-block there. We ignore the new_addr argument
2095 USI prev_addr
= addr
;
2096 USI prev_len
= old_len
;
2099 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2102 if (mapped_addr
> (USI
) -8192)
2104 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2108 retval
= mapped_addr
;
2111 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2113 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2115 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2116 mapped_addr
, 8192) != 8192)
2120 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2121 prev_addr
, prev_len
) != 0)
2125 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2129 case TARGET_SYS_poll
:
2131 int npollfds
= arg2
;
2147 /* Check that this is the expected poll call from
2148 linuxthreads/manager.c; we don't support anything else.
2149 Remember, fd == 0 isn't supported. */
2151 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2153 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2156 || ((cb
->fstat
) (cb
, fd
, &buf
) != 0
2157 || (buf
.st_mode
& S_IFIFO
) == 0)
2158 || current_cpu
->thread_data
== NULL
)
2161 = cris_unknown_syscall (current_cpu
, pc
,
2162 "Unimplemented poll syscall "
2163 "(0x%lx: [0x%x, 0x%x, x], "
2165 (unsigned long) arg1
, fd
, events
,
2166 (unsigned long) arg2
,
2167 (unsigned long) arg3
);
2173 /* Iterate over threads; find a marker that a writer is
2174 sleeping, waiting for a reader. */
2175 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2176 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2177 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2179 revents
= TARGET_POLLIN
;
2184 /* Timeout decreases with whatever time passed between the
2185 last syscall and this. That's not exactly right for the
2186 first call, but it's close enough that it isn't
2187 worthwhile to complicate matters by making that a special
2190 -= (TARGET_TIME_MS (current_cpu
)
2191 - (current_cpu
->thread_data
[threadno
].last_execution
));
2193 /* Arrange to repeat this syscall until timeout or event,
2194 decreasing timeout at each iteration. */
2195 if (timeout
> 0 && revents
== 0)
2197 bfd_byte timeout_buf
[4];
2199 bfd_putl32 (timeout
, timeout_buf
);
2200 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2201 H_GR_R12
, timeout_buf
, 4);
2202 sim_pc_set (current_cpu
, pc
);
2207 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2212 case TARGET_SYS_time
:
2214 retval
= (int) (*cb
->time
) (cb
, 0L);
2216 /* At time of this writing, CB_SYSCALL_time doesn't do the
2217 part of setting *arg1 to the return value. */
2219 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2223 case TARGET_SYS_gettimeofday
:
2226 USI ts
= TARGET_TIME (current_cpu
);
2227 USI tms
= TARGET_TIME_MS (current_cpu
);
2229 /* First dword is seconds since TARGET_EPOCH. */
2230 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2232 /* Second dword is microseconds. */
2233 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2234 (tms
% 1000) * 1000);
2238 /* Time-zone info is always cleared. */
2239 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2240 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2245 case TARGET_SYS_llseek
:
2247 /* If it fits, tweak parameters to fit the "generic" 32-bit
2248 lseek and use that. */
2256 if (!((offs_hi
== 0 && offs_lo
>= 0)
2257 || (offs_hi
== -1 && offs_lo
< 0)))
2260 = cris_unknown_syscall (current_cpu
, pc
,
2261 "Unimplemented llseek offset,"
2262 " fd %d: 0x%x:0x%x\n",
2263 fd
, (unsigned) arg2
,
2268 s
.func
= TARGET_SYS_lseek
;
2271 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2273 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2275 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2278 retval
= -s
.errcode
;
2281 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2283 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2284 s
.result
< 0 ? -1 : 0);
2289 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2292 void *iov_base; Starting address
2293 size_t iov_len; Number of bytes to transfer
2295 case TARGET_SYS_writev
:
2303 /* We'll ignore strict error-handling and just do multiple write calls. */
2304 for (i
= 0; i
< iovcnt
; i
++)
2308 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2311 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2314 s
.func
= TARGET_SYS_write
;
2319 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2321 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2323 if (sysret
!= iov_len
)
2338 /* This one does have a generic callback function, but at the time
2339 of this writing, cb_syscall does not have code for it, and we
2340 need target-specific code for the threads implementation
2342 case TARGET_SYS_kill
:
2349 /* At kill(2), glibc sets signal masks such that the thread
2350 machinery is initialized. Still, there is and was only
2352 if (current_cpu
->max_threadid
== 0)
2354 if (pid
!= TARGET_PID
)
2356 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2360 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2361 if (sig
== TARGET_SIGABRT
)
2362 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2363 the end-point for failing GCC test-cases. */
2364 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2368 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2369 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2373 /* This will not be reached. */
2377 retval
= deliver_signal (current_cpu
, sig
, pid
);
2381 case TARGET_SYS_rt_sigprocmask
:
2388 if (how
!= TARGET_SIG_BLOCK
2389 && how
!= TARGET_SIG_SETMASK
2390 && how
!= TARGET_SIG_UNBLOCK
)
2393 = cris_unknown_syscall (current_cpu
, pc
,
2394 "Unimplemented rt_sigprocmask "
2395 "syscall (0x%x, 0x%x, 0x%x)\n",
2403 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2406 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2409 /* The sigmask is kept in the per-thread data, so we may
2410 need to create the first one. */
2411 if (current_cpu
->thread_data
== NULL
)
2412 make_first_thread (current_cpu
);
2414 if (how
== TARGET_SIG_SETMASK
)
2415 for (i
= 0; i
< 64; i
++)
2416 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2418 for (i
= 0; i
< 32; i
++)
2419 if ((set_low
& (1 << i
)))
2420 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2421 = (how
!= TARGET_SIG_UNBLOCK
);
2423 for (i
= 0; i
< 31; i
++)
2424 if ((set_high
& (1 << i
)))
2425 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2426 = (how
!= TARGET_SIG_UNBLOCK
);
2428 /* The mask changed, so a signal may be unblocked for
2430 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2438 for (i
= 0; i
< 32; i
++)
2439 if (current_cpu
->thread_data
[threadno
]
2440 .sigdata
[i
+ 1].blocked
)
2442 for (i
= 0; i
< 31; i
++)
2443 if (current_cpu
->thread_data
[threadno
]
2444 .sigdata
[i
+ 33].blocked
)
2447 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2448 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2455 case TARGET_SYS_sigreturn
:
2459 int was_sigsuspended
;
2461 if (current_cpu
->thread_data
== NULL
2462 /* The CPU context is saved with the simulator data, not
2463 on the stack as in the real world. */
2464 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2468 = cris_unknown_syscall (current_cpu
, pc
,
2469 "Invalid sigreturn syscall: "
2470 "no signal handler active "
2471 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2473 (unsigned long) arg1
,
2474 (unsigned long) arg2
,
2475 (unsigned long) arg3
,
2476 (unsigned long) arg4
,
2477 (unsigned long) arg5
,
2478 (unsigned long) arg6
);
2483 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2485 /* Restore the sigmask, either from the stack copy made when
2486 the sighandler was called, or from the saved state
2487 specifically for sigsuspend(2). */
2488 if (was_sigsuspended
)
2490 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2491 for (i
= 0; i
< 64; i
++)
2492 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2493 = current_cpu
->thread_data
[threadno
]
2494 .sigdata
[i
].blocked_suspendsave
;
2502 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2503 H_GR_SP
, regbuf
, 4);
2504 sp
= bfd_getl32 (regbuf
);
2506 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2508 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2510 for (i
= 0; i
< 32; i
++)
2511 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2512 = (set_low
& (1 << i
)) != 0;
2513 for (i
= 0; i
< 31; i
++)
2514 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2515 = (set_high
& (1 << i
)) != 0;
2518 /* The mask changed, so a signal may be unblocked for
2520 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2522 memcpy (¤t_cpu
->cpu_data_placeholder
,
2523 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2524 current_cpu
->thread_cpu_data_size
);
2525 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2526 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2528 /* The return value must come from the saved R10. */
2529 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2530 retval
= bfd_getl32 (regbuf
);
2532 /* We must also break the "sigsuspension loop". */
2533 if (was_sigsuspended
)
2534 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2538 case TARGET_SYS_rt_sigsuspend
:
2546 = cris_unknown_syscall (current_cpu
, pc
,
2547 "Unimplemented rt_sigsuspend syscall"
2548 " arguments (0x%lx, 0x%lx)\n",
2549 (unsigned long) arg1
,
2550 (unsigned long) arg2
);
2554 /* Don't change the signal mask if we're already in
2555 sigsuspend state (i.e. this syscall is a rerun). */
2556 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2559 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2562 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2566 /* Save the current sigmask and insert the user-supplied
2568 for (i
= 0; i
< 32; i
++)
2570 current_cpu
->thread_data
[threadno
]
2571 .sigdata
[i
+ 1].blocked_suspendsave
2572 = current_cpu
->thread_data
[threadno
]
2573 .sigdata
[i
+ 1].blocked
;
2575 current_cpu
->thread_data
[threadno
]
2576 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2578 for (i
= 0; i
< 31; i
++)
2580 current_cpu
->thread_data
[threadno
]
2581 .sigdata
[i
+ 33].blocked_suspendsave
2582 = current_cpu
->thread_data
[threadno
]
2583 .sigdata
[i
+ 33].blocked
;
2584 current_cpu
->thread_data
[threadno
]
2585 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2588 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2590 /* The mask changed, so a signal may be unblocked for
2592 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2595 /* Because we don't use arg1 (newsetp) when this syscall is
2596 rerun, it doesn't matter that we overwrite it with the
2597 (constant) return value. */
2598 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2599 sim_pc_set (current_cpu
, pc
);
2603 /* Add case labels here for other syscalls using the 32-bit
2604 "struct stat", provided they have a corresponding simulator
2605 function of course. */
2606 case TARGET_SYS_stat
:
2607 case TARGET_SYS_fstat
:
2609 /* As long as the infrastructure doesn't cache anything
2610 related to the stat mapping, this trick gets us a dual
2611 "struct stat"-type mapping in the least error-prone way. */
2612 const char *saved_map
= cb
->stat_map
;
2613 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2615 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2616 cb
->stat_map
= stat32_map
;
2618 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2621 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2624 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2626 cb
->stat_map
= saved_map
;
2627 cb
->syscall_map
= saved_syscall_map
;
2631 case TARGET_SYS_getcwd
:
2636 char *cwd
= xmalloc (SIM_PATHMAX
);
2637 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2640 /* FIXME: When and if we support chdir, we need something
2641 a bit more elaborate. */
2642 if (simulator_sysroot
[0] != '\0')
2645 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2646 if (strlen (cwd
) + 1 <= size
)
2648 retval
= strlen (cwd
) + 1;
2649 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2651 != (unsigned int) retval
)
2652 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2658 case TARGET_SYS_access
:
2662 char *pbuf
= xmalloc (SIM_PATHMAX
);
2667 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2669 strcpy (pbuf
, simulator_sysroot
);
2670 o
+= strlen (simulator_sysroot
);
2673 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2676 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2677 if (pbuf
[i
+ o
] == 0)
2681 if (i
+ o
== SIM_PATHMAX
)
2683 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2687 /* Assert that we don't get calls for files for which we
2688 don't have support. */
2689 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2692 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2699 if (access (pbuf
, hmode
) != 0)
2700 retval
= -cb_host_to_target_errno (cb
, errno
);
2708 case TARGET_SYS_readlink
:
2713 char *pbuf
= xmalloc (SIM_PATHMAX
);
2714 char *lbuf
= xmalloc (SIM_PATHMAX
);
2715 char *lbuf_alloc
= lbuf
;
2720 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2722 strcpy (pbuf
, simulator_sysroot
);
2723 o
+= strlen (simulator_sysroot
);
2726 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2729 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2730 if (pbuf
[i
+ o
] == 0)
2734 if (i
+ o
== SIM_PATHMAX
)
2736 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2740 /* Intervene calls for certain files expected in the target
2741 proc file system. */
2742 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2743 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2746 = (STATE_PROG_ARGV (sd
) != NULL
2747 ? *STATE_PROG_ARGV (sd
) : NULL
);
2749 if (argv0
== NULL
|| *argv0
== '.')
2752 = cris_unknown_syscall (current_cpu
, pc
,
2753 "Unimplemented readlink syscall "
2754 "(0x%lx: [\"%s\"], 0x%lx)\n",
2755 (unsigned long) arg1
, pbuf
,
2756 (unsigned long) arg2
);
2759 else if (*argv0
== '/')
2761 if (strncmp (simulator_sysroot
, argv0
,
2762 strlen (simulator_sysroot
)) == 0)
2763 argv0
+= strlen (simulator_sysroot
);
2765 strcpy (lbuf
, argv0
);
2766 nchars
= strlen (argv0
) + 1;
2770 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2771 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2773 if (strncmp (simulator_sysroot
, lbuf
,
2774 strlen (simulator_sysroot
)) == 0)
2775 lbuf
+= strlen (simulator_sysroot
);
2778 strcat (lbuf
, argv0
);
2779 nchars
= strlen (lbuf
) + 1;
2786 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2788 /* We trust that the readlink result returns a *relative*
2789 link, or one already adjusted for the file-path-prefix.
2790 (We can't generally tell the difference, so we go with
2791 the easiest decision; no adjustment.) */
2795 retval
= -cb_host_to_target_errno (cb
, errno
);
2799 if (bufsiz
< nchars
)
2802 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2803 buf
, nchars
) != (unsigned int) nchars
)
2804 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2813 case TARGET_SYS_sched_getscheduler
:
2817 /* FIXME: Search (other) existing threads. */
2818 if (pid
!= 0 && pid
!= TARGET_PID
)
2819 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2821 retval
= TARGET_SCHED_OTHER
;
2825 case TARGET_SYS_sched_getparam
:
2831 struct sched_param {
2835 if (pid
!= 0 && pid
!= TARGET_PID
)
2836 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2839 /* FIXME: Save scheduler setting before threads are
2841 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2842 current_cpu
->thread_data
!= NULL
2844 ->thread_data
[threadno
]
2852 case TARGET_SYS_sched_setparam
:
2857 if ((pid
!= 0 && pid
!= TARGET_PID
)
2858 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2860 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2866 case TARGET_SYS_sched_setscheduler
:
2872 if ((pid
!= 0 && pid
!= TARGET_PID
)
2873 || policy
!= TARGET_SCHED_OTHER
2874 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2876 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2878 /* FIXME: Save scheduler setting to be read in later
2879 sched_getparam calls. */
2884 case TARGET_SYS_sched_yield
:
2885 /* We reschedule to the next thread after a syscall anyway, so
2886 we don't have to do anything here than to set the return
2891 case TARGET_SYS_sched_get_priority_min
:
2892 case TARGET_SYS_sched_get_priority_max
:
2894 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2899 case TARGET_SYS_ugetrlimit
:
2901 unsigned int curlim
, maxlim
;
2902 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2904 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2910 unsigned long rlim_cur;
2911 unsigned long rlim_max;
2913 if (arg1
== TARGET_RLIMIT_NOFILE
)
2915 /* Sadly a very low limit. Better not lie, though. */
2916 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2918 else /* arg1 == TARGET_RLIMIT_STACK */
2920 maxlim
= 0xffffffff;
2923 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2924 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2929 case TARGET_SYS_setrlimit
:
2930 if (arg1
!= TARGET_RLIMIT_STACK
)
2932 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2935 /* FIXME: Save values for future ugetrlimit calls. */
2939 /* Provide a very limited subset of the sysctl functions, and
2940 abort for the rest. */
2941 case TARGET_SYS__sysctl
:
2944 struct __sysctl_args {
2951 unsigned long __unused[4];
2953 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2954 SI name0
= name
== 0
2955 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2956 SI name1
= name
== 0
2957 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2959 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2961 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2963 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2964 SI oldlen
= oldlenp
== 0
2965 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2967 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2969 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2971 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2973 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2974 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2976 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
2977 sizeof (TARGET_UTSNAME
));
2979 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
2980 TARGET_UTSNAME
, oldval
,
2982 != (unsigned int) to_write
)
2983 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2990 = cris_unknown_syscall (current_cpu
, pc
,
2991 "Unimplemented _sysctl syscall "
2992 "(0x%lx: [0x%lx, 0x%lx],"
2993 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2994 (unsigned long) name
,
2995 (unsigned long) name0
,
2996 (unsigned long) name1
,
2997 (unsigned long) nlen
,
2998 (unsigned long) oldval
,
2999 (unsigned long) oldlenp
,
3000 (unsigned long) newval
,
3001 (unsigned long) newlen
);
3005 case TARGET_SYS_exit
:
3007 /* Here for all but the last thread. */
3010 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3012 = (current_cpu
->thread_data
[threadno
].parent_threadid
3014 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3016 /* Any children are now all orphans. */
3017 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3018 if (current_cpu
->thread_data
[i
].parent_threadid
3019 == current_cpu
->thread_data
[threadno
].threadid
)
3020 /* Make getppid(2) return 1 for them, poor little ones. */
3021 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3023 /* Free the cpu context data. When the parent has received
3024 the exit status, we'll clear the entry too. */
3025 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3026 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3027 current_cpu
->m1threads
--;
3030 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3032 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3036 /* Still, we may want to support non-zero exit values. */
3037 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3040 deliver_signal (current_cpu
, exitsig
, ppid
);
3044 case TARGET_SYS_clone
:
3046 int nthreads
= current_cpu
->m1threads
+ 1;
3047 void *thread_cpu_data
;
3048 bfd_byte old_sp_buf
[4];
3050 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3053 /* That's right, the syscall clone arguments are reversed
3054 compared to sys_clone notes in clone(2) and compared to
3055 other Linux ports (i.e. it's the same order as in the
3056 clone(2) libcall). */
3060 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3062 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3066 /* FIXME: Implement the low byte. */
3067 if ((flags
& ~TARGET_CSIGNAL
) !=
3070 | TARGET_CLONE_FILES
3071 | TARGET_CLONE_SIGHAND
)
3075 = cris_unknown_syscall (current_cpu
, pc
,
3076 "Unimplemented clone syscall "
3078 (unsigned long) arg1
,
3079 (unsigned long) arg2
);
3083 if (current_cpu
->thread_data
== NULL
)
3084 make_first_thread (current_cpu
);
3086 /* The created thread will get the new SP and a cleared R10.
3087 Since it's created out of a copy of the old thread and we
3088 don't have a set-register-function that just take the
3089 cpu_data as a parameter, we set the childs values first,
3090 and write back or overwrite them in the parent after the
3092 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3093 H_GR_SP
, old_sp_buf
, 4);
3094 bfd_putl32 (newsp
, sp_buf
);
3095 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3096 H_GR_SP
, sp_buf
, 4);
3097 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3098 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3101 ->make_thread_cpu_data
) (current_cpu
,
3102 ¤t_cpu
->cpu_data_placeholder
);
3103 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3104 H_GR_SP
, old_sp_buf
, 4);
3106 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3108 /* Find an unused slot. After a few threads have been created
3109 and exited, the array is expected to be a bit fragmented.
3110 We don't reuse the first entry, though, that of the
3112 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3113 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3114 /* Don't reuse a zombied entry. */
3115 && current_cpu
->thread_data
[i
].threadid
== 0)
3118 memcpy (¤t_cpu
->thread_data
[i
],
3119 ¤t_cpu
->thread_data
[threadno
],
3120 sizeof (current_cpu
->thread_data
[i
]));
3121 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3122 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3123 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3124 current_cpu
->thread_data
[i
].parent_threadid
3125 = current_cpu
->thread_data
[threadno
].threadid
;
3126 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3127 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3128 current_cpu
->thread_data
[i
].at_syscall
= 0;
3129 current_cpu
->thread_data
[i
].sigpending
= 0;
3130 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3131 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3132 current_cpu
->m1threads
= nthreads
;
3136 /* Better watch these in case they do something necessary. */
3137 case TARGET_SYS_socketcall
:
3138 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3141 unimplemented_syscall
:
3144 = cris_unknown_syscall (current_cpu
, pc
,
3145 "Unimplemented syscall: %d "
3146 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3147 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3152 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3153 if (callnum
== TARGET_SYS_open
)
3155 current_cpu
->last_open_fd
= retval
;
3156 current_cpu
->last_open_flags
= arg2
;
3159 current_cpu
->last_syscall
= callnum
;
3161 /* A system call is a rescheduling point. For the time being, we don't
3162 reschedule anywhere else. */
3163 if (current_cpu
->m1threads
!= 0
3164 /* We need to schedule off from an exiting thread that is the
3166 || (current_cpu
->thread_data
!= NULL
3167 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3169 bfd_byte retval_buf
[4];
3171 current_cpu
->thread_data
[threadno
].last_execution
3172 = TARGET_TIME_MS (current_cpu
);
3173 bfd_putl32 (retval
, retval_buf
);
3174 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3176 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3177 reschedule (current_cpu
);
3179 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3180 retval
= bfd_getl32 (retval_buf
);
3186 /* Callback from simulator write saying that the pipe at (reader, writer)
3187 is now non-empty (so the writer should wait until the pipe is empty, at
3188 least not write to this or any other pipe). Simplest is to just wait
3189 until the pipe is empty. */
3192 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3193 int reader
, int writer
)
3195 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3196 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3198 /* It's the current thread: we just have to re-run the current
3199 syscall instruction (presumably "break 13") and change the syscall
3200 to the special simulator-wait code. Oh, and set a marker that
3201 we're waiting, so we can disambiguate the special call from a
3204 This function may be called multiple times between cris_pipe_empty,
3205 but we must avoid e.g. decreasing PC every time. Check fd markers
3207 if (cpu
->thread_data
== NULL
)
3209 sim_io_eprintf (CPU_STATE (cpu
),
3210 "Terminating simulation due to writing pipe rd:wr %d:%d"
3211 " from one single thread\n", reader
, writer
);
3212 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3213 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3215 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3217 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3218 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3219 /* FIXME: We really shouldn't change registers other than R10 in
3220 syscalls (like R9), here or elsewhere. */
3221 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3222 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3226 /* Callback from simulator close or read call saying that the pipe at
3227 (reader, writer) is now empty (so the writer can write again, perhaps
3228 leave a waiting state). If there are bytes remaining, they couldn't be
3229 consumed (perhaps due to the pipe closing). */
3232 cris_pipe_empty (host_callback
*cb
,
3237 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3238 bfd_byte r10_buf
[4];
3240 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3242 /* We need to find the thread that waits for this pipe. */
3243 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3244 if (cpu
->thread_data
[i
].cpu_context
3245 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3249 /* Temporarily switch to this cpu context, so we can change the
3250 PC by ordinary calls. */
3252 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3253 &cpu
->cpu_data_placeholder
,
3254 cpu
->thread_cpu_data_size
);
3255 memcpy (&cpu
->cpu_data_placeholder
,
3256 cpu
->thread_data
[i
].cpu_context
,
3257 cpu
->thread_cpu_data_size
);
3259 /* The return value is supposed to contain the number of
3260 written bytes, which is the number of bytes requested and
3261 returned at the write call. You might think the right
3262 thing is to adjust the return-value to be only the
3263 *consumed* number of bytes, but it isn't. We're only
3264 called if the pipe buffer is fully consumed or it is being
3265 closed, possibly with remaining bytes. For the latter
3266 case, the writer is still supposed to see success for
3267 PIPE_BUF bytes (a constant which we happen to know and is
3268 unlikely to change). The return value may also be a
3269 negative number; an error value. This case is covered
3270 because "remaining" is always >= 0. */
3271 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3272 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3273 if (retval
- remaining
> TARGET_PIPE_BUF
)
3275 bfd_putl32 (retval
- remaining
, r10_buf
);
3276 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3278 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3279 memcpy (cpu
->thread_data
[i
].cpu_context
,
3280 &cpu
->cpu_data_placeholder
,
3281 cpu
->thread_cpu_data_size
);
3282 memcpy (&cpu
->cpu_data_placeholder
,
3283 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3284 cpu
->thread_cpu_data_size
);
3285 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3286 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3293 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3296 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
3298 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
3304 /* Set target-specific callback data. */
3307 cris_set_callbacks (host_callback
*cb
)
3309 /* Yeargh, have to cast away constness to avoid warnings. */
3310 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3311 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3313 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3314 parameter to cb_store_target_endian will make st_size negative.
3315 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3316 *unsigned*, and/or add syntax for signed-ness. */
3317 cb
->stat_map
= stat_map
;
3318 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3319 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3320 cb
->pipe_empty
= cris_pipe_empty
;
3321 cb
->time
= cris_time
;
3324 /* Process an address exception. */
3327 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3328 unsigned int map
, int nr_bytes
, address_word addr
,
3329 transfer_type transfer
, sim_core_signals sig
)
3331 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,