1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004, 2005 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 2, or (at your option)
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 along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "sim-options.h"
24 /* 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_kill 37
69 #define TARGET_SYS_rename 38
70 #define TARGET_SYS_pipe 42
71 #define TARGET_SYS_brk 45
72 #define TARGET_SYS_ioctl 54
73 #define TARGET_SYS_fcntl 55
74 #define TARGET_SYS_getppid 64
75 #define TARGET_SYS_setrlimit 75
76 #define TARGET_SYS_gettimeofday 78
77 #define TARGET_SYS_readlink 85
78 #define TARGET_SYS_munmap 91
79 #define TARGET_SYS_truncate 92
80 #define TARGET_SYS_ftruncate 93
81 #define TARGET_SYS_socketcall 102
82 #define TARGET_SYS_stat 106
83 #define TARGET_SYS_fstat 108
84 #define TARGET_SYS_wait4 114
85 #define TARGET_SYS_sigreturn 119
86 #define TARGET_SYS_clone 120
87 #define TARGET_SYS_uname 122
88 #define TARGET_SYS_mprotect 125
89 #define TARGET_SYS_llseek 140
90 #define TARGET_SYS__sysctl 149
91 #define TARGET_SYS_sched_setparam 154
92 #define TARGET_SYS_sched_getparam 155
93 #define TARGET_SYS_sched_setscheduler 156
94 #define TARGET_SYS_sched_getscheduler 157
95 #define TARGET_SYS_sched_yield 158
96 #define TARGET_SYS_sched_get_priority_max 159
97 #define TARGET_SYS_sched_get_priority_min 160
98 #define TARGET_SYS_mremap 163
99 #define TARGET_SYS_poll 168
100 #define TARGET_SYS_rt_sigaction 174
101 #define TARGET_SYS_rt_sigprocmask 175
102 #define TARGET_SYS_rt_sigsuspend 179
103 #define TARGET_SYS_getcwd 183
104 #define TARGET_SYS_ugetrlimit 191
105 #define TARGET_SYS_mmap2 192
106 #define TARGET_SYS_stat64 195
107 #define TARGET_SYS_lstat64 196
108 #define TARGET_SYS_fstat64 197
109 #define TARGET_SYS_geteuid32 201
110 #define TARGET_SYS_getuid32 199
111 #define TARGET_SYS_getegid32 202
112 #define TARGET_SYS_getgid32 200
113 #define TARGET_SYS_fcntl64 221
115 #define TARGET_PROT_READ 0x1
116 #define TARGET_PROT_WRITE 0x2
117 #define TARGET_PROT_EXEC 0x4
118 #define TARGET_PROT_NONE 0x0
120 #define TARGET_MAP_SHARED 0x01
121 #define TARGET_MAP_PRIVATE 0x02
122 #define TARGET_MAP_TYPE 0x0f
123 #define TARGET_MAP_FIXED 0x10
124 #define TARGET_MAP_ANONYMOUS 0x20
126 #define TARGET_CTL_KERN 1
127 #define TARGET_CTL_VM 2
128 #define TARGET_CTL_NET 3
129 #define TARGET_CTL_PROC 4
130 #define TARGET_CTL_FS 5
131 #define TARGET_CTL_DEBUG 6
132 #define TARGET_CTL_DEV 7
133 #define TARGET_CTL_BUS 8
134 #define TARGET_CTL_ABI 9
136 #define TARGET_CTL_KERN_VERSION 4
139 #define TARGET_MREMAP_MAYMOVE 1
140 #define TARGET_MREMAP_FIXED 2
142 #define TARGET_TCGETS 0x5401
144 #define TARGET_UTSNAME "#38 Sun Apr 1 00:00:00 MET 2001"
146 /* Seconds since the above date + 10 minutes. */
147 #define TARGET_EPOCH 986080200
149 /* Milliseconds since start of run. We use the number of syscalls to
150 avoid introducing noise in the execution time. */
151 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
153 /* Seconds as in time(2). */
154 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
156 #define TARGET_SCHED_OTHER 0
158 #define TARGET_RLIMIT_STACK 3
159 #define TARGET_RLIMIT_NOFILE 7
161 #define SIM_TARGET_MAX_THREADS 64
162 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
164 /* From linux/sched.h. */
165 #define TARGET_CSIGNAL 0x000000ff
166 #define TARGET_CLONE_VM 0x00000100
167 #define TARGET_CLONE_FS 0x00000200
168 #define TARGET_CLONE_FILES 0x00000400
169 #define TARGET_CLONE_SIGHAND 0x00000800
170 #define TARGET_CLONE_PID 0x00001000
171 #define TARGET_CLONE_PTRACE 0x00002000
172 #define TARGET_CLONE_VFORK 0x00004000
173 #define TARGET_CLONE_PARENT 0x00008000
174 #define TARGET_CLONE_THREAD 0x00010000
175 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
177 /* From asm-cris/poll.h. */
178 #define TARGET_POLLIN 1
180 /* From asm-cris/signal.h. */
181 #define TARGET_SIG_BLOCK 0
182 #define TARGET_SIG_UNBLOCK 1
183 #define TARGET_SIG_SETMASK 2
185 #define TARGET_SIG_DFL 0
186 #define TARGET_SIG_IGN 1
187 #define TARGET_SIG_ERR ((USI)-1)
189 #define TARGET_SIGHUP 1
190 #define TARGET_SIGINT 2
191 #define TARGET_SIGQUIT 3
192 #define TARGET_SIGILL 4
193 #define TARGET_SIGTRAP 5
194 #define TARGET_SIGABRT 6
195 #define TARGET_SIGIOT 6
196 #define TARGET_SIGBUS 7
197 #define TARGET_SIGFPE 8
198 #define TARGET_SIGKILL 9
199 #define TARGET_SIGUSR1 10
200 #define TARGET_SIGSEGV 11
201 #define TARGET_SIGUSR2 12
202 #define TARGET_SIGPIPE 13
203 #define TARGET_SIGALRM 14
204 #define TARGET_SIGTERM 15
205 #define TARGET_SIGSTKFLT 16
206 #define TARGET_SIGCHLD 17
207 #define TARGET_SIGCONT 18
208 #define TARGET_SIGSTOP 19
209 #define TARGET_SIGTSTP 20
210 #define TARGET_SIGTTIN 21
211 #define TARGET_SIGTTOU 22
212 #define TARGET_SIGURG 23
213 #define TARGET_SIGXCPU 24
214 #define TARGET_SIGXFSZ 25
215 #define TARGET_SIGVTALRM 26
216 #define TARGET_SIGPROF 27
217 #define TARGET_SIGWINCH 28
218 #define TARGET_SIGIO 29
219 #define TARGET_SIGPOLL SIGIO
220 /* Actually commented out in the kernel header. */
221 #define TARGET_SIGLOST 29
222 #define TARGET_SIGPWR 30
223 #define TARGET_SIGSYS 31
225 /* From include/asm-cris/signal.h. */
226 #define TARGET_SA_NOCLDSTOP 0x00000001
227 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
228 #define TARGET_SA_SIGINFO 0x00000004
229 #define TARGET_SA_ONSTACK 0x08000000
230 #define TARGET_SA_RESTART 0x10000000
231 #define TARGET_SA_NODEFER 0x40000000
232 #define TARGET_SA_RESETHAND 0x80000000
233 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
234 #define TARGET_SA_RESTORER 0x04000000
236 /* From linux/wait.h. */
237 #define TARGET_WNOHANG 1
238 #define TARGET_WUNTRACED 2
239 #define TARGET___WNOTHREAD 0x20000000
240 #define TARGET___WALL 0x40000000
241 #define TARGET___WCLONE 0x80000000
243 /* From linux/limits.h. */
244 #define TARGET_PIPE_BUF 4096
246 static const char stat_map
[] =
247 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
248 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
249 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
252 static const CB_TARGET_DEFS_MAP syscall_map
[] =
254 { CB_SYS_open
, TARGET_SYS_open
},
255 { CB_SYS_close
, TARGET_SYS_close
},
256 { CB_SYS_read
, TARGET_SYS_read
},
257 { CB_SYS_write
, TARGET_SYS_write
},
258 { CB_SYS_lseek
, TARGET_SYS_lseek
},
259 { CB_SYS_unlink
, TARGET_SYS_unlink
},
260 { CB_SYS_getpid
, TARGET_SYS_getpid
},
261 { CB_SYS_fstat
, TARGET_SYS_fstat64
},
262 { CB_SYS_lstat
, TARGET_SYS_lstat64
},
263 { CB_SYS_stat
, TARGET_SYS_stat64
},
264 { CB_SYS_pipe
, TARGET_SYS_pipe
},
265 { CB_SYS_rename
, TARGET_SYS_rename
},
266 { CB_SYS_truncate
, TARGET_SYS_truncate
},
267 { CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
271 /* An older, 32-bit-only stat mapping. */
272 static const char stat32_map
[] =
273 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
274 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
275 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
277 /* Map for calls using the 32-bit struct stat. Primarily used by the
278 newlib Linux mapping. */
279 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
281 { CB_SYS_fstat
, TARGET_SYS_fstat
},
282 { CB_SYS_stat
, TARGET_SYS_stat
},
286 /* Giving the true value for the running sim process will lead to
287 non-time-invariant behavior. */
288 #define TARGET_PID 42
290 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
291 we did, we'd still don't get a register number with the "16" offset. */
292 #define TARGET_SRP_REGNUM (16+11)
294 /* Extracted by applying
295 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
296 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
297 adjusting the synonyms. */
299 static const CB_TARGET_DEFS_MAP errno_map
[] =
407 { ENAMETOOLONG
, 36 },
566 { EDESTADDRREQ
, 89 },
577 #ifdef EPROTONOSUPPORT
578 { EPROTONOSUPPORT
, 93 },
580 #ifdef ESOCKTNOSUPPORT
581 { ESOCKTNOSUPPORT
, 94 },
587 { EPFNOSUPPORT
, 96 },
590 { EAFNOSUPPORT
, 97 },
596 { EADDRNOTAVAIL
, 99 },
602 { ENETUNREACH
, 101 },
608 { ECONNABORTED
, 103 },
626 { ETOOMANYREFS
, 109 },
632 { ECONNREFUSED
, 111 },
638 { EHOSTUNREACH
, 113 },
644 { EINPROGRESS
, 115 },
671 { EMEDIUMTYPE
, 124 },
676 /* Extracted by applying
677 perl -ne 'if ($_ =~ /^#define/) { split;
678 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
679 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
680 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
681 installation and removing synonyms and unnecessary items. Don't
682 forget the end-marker. */
684 /* These we treat specially, as they're used in the fcntl F_GETFL
685 syscall. For consistency, open_map is also manually edited to use
687 #define TARGET_O_ACCMODE 0x3
688 #define TARGET_O_RDONLY 0x0
689 #define TARGET_O_WRONLY 0x1
691 static const CB_TARGET_DEFS_MAP open_map
[] = {
693 { O_ACCMODE
, TARGET_O_ACCMODE
},
696 { O_RDONLY
, TARGET_O_RDONLY
},
699 { O_WRONLY
, TARGET_O_WRONLY
},
720 { O_NONBLOCK
, 0x800 },
732 { O_DIRECT
, 0x4000 },
735 { O_LARGEFILE
, 0x8000 },
738 { O_DIRECTORY
, 0x10000 },
741 { O_NOFOLLOW
, 0x20000 },
746 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
747 static SIM_CPU
*current_cpu_for_cb_callback
;
749 static int syscall_read_mem (host_callback
*, struct cb_syscall
*,
750 unsigned long, char *, int);
751 static int syscall_write_mem (host_callback
*, struct cb_syscall
*,
752 unsigned long, const char *, int);
753 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
755 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
757 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
759 static void dump_statistics (SIM_CPU
*current_cpu
);
760 static void make_first_thread (SIM_CPU
*current_cpu
);
762 /* Read/write functions for system call interface. */
765 syscall_read_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
766 struct cb_syscall
*sc
,
767 unsigned long taddr
, char *buf
, int bytes
)
769 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
770 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
772 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
776 syscall_write_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
777 struct cb_syscall
*sc
,
778 unsigned long taddr
, const char *buf
, int bytes
)
780 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
781 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
783 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
786 /* When we risk running self-modified code (as in trampolines), this is
787 called from special-case insns. The silicon CRIS CPU:s have enough
788 cache snooping implemented making this a simulator-only issue. Tests:
789 gcc.c-torture/execute/931002-1.c execution, -O3 -g
790 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
793 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
794 USI pc ATTRIBUTE_UNUSED
)
796 SIM_DESC sd
= CPU_STATE (current_cpu
);
799 if (USING_SCACHE_P (sd
))
800 scache_flush_cpu (current_cpu
);
804 /* Output statistics at the end of a run. */
806 dump_statistics (SIM_CPU
*current_cpu
)
808 SIM_DESC sd
= CPU_STATE (current_cpu
);
809 CRIS_MISC_PROFILE
*profp
810 = CPU_CRIS_MISC_PROFILE (current_cpu
);
811 unsigned64 total
= profp
->basic_cycle_count
;
812 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
814 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
815 what's included in the "total" count only. */
816 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
817 & FLAG_CRIS_MISC_PROFILE_ALL
)
819 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
822 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
824 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
825 total
+= profp
->unaligned_mem_dword_count
;
828 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
829 textmsg
= "Schedulable clock cycles, total @: %llu\n";
831 += (profp
->memsrc_stall_count
832 + profp
->memraw_stall_count
833 + profp
->movemsrc_stall_count
834 + profp
->movemdst_stall_count
835 + profp
->mulsrc_stall_count
836 + profp
->jumpsrc_stall_count
837 + profp
->unaligned_mem_dword_count
);
840 case FLAG_CRIS_MISC_PROFILE_ALL
:
841 textmsg
= "All accounted 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
->movemaddr_stall_count
848 + profp
->mulsrc_stall_count
849 + profp
->jumpsrc_stall_count
850 + profp
->branch_stall_count
851 + profp
->jumptarget_stall_count
852 + profp
->unaligned_mem_dword_count
);
859 "Internal inconsistency at %s:%d",
861 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
862 sim_stopped
, SIM_SIGILL
);
865 /* Historically, these messages have gone to stderr, so we'll keep it
866 that way. It's also easier to then tell it from normal program
867 output. FIXME: Add redirect option like "run -e file". */
868 sim_io_eprintf (sd
, textmsg
, total
);
870 /* For v32, unaligned_mem_dword_count should always be 0. For
871 v10, memsrc_stall_count should always be 0. */
872 sim_io_eprintf (sd
, "Memory source stall cycles: %lld\n",
873 profp
->memsrc_stall_count
874 + profp
->unaligned_mem_dword_count
);
875 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %lld\n",
876 profp
->memraw_stall_count
);
877 sim_io_eprintf (sd
, "Movem source stall cycles: %lld\n",
878 profp
->movemsrc_stall_count
);
879 sim_io_eprintf (sd
, "Movem destination stall cycles: %lld\n",
880 profp
->movemdst_stall_count
);
881 sim_io_eprintf (sd
, "Movem address stall cycles: %lld\n",
882 profp
->movemaddr_stall_count
);
883 sim_io_eprintf (sd
, "Multiplication source stall cycles: %lld\n",
884 profp
->mulsrc_stall_count
);
885 sim_io_eprintf (sd
, "Jump source stall cycles: %lld\n",
886 profp
->jumpsrc_stall_count
);
887 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %lld\n",
888 profp
->branch_stall_count
);
889 sim_io_eprintf (sd
, "Jump target stall cycles: %lld\n",
890 profp
->jumptarget_stall_count
);
893 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
894 Return 1 if a overlap detected, 0 otherwise. */
897 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
898 struct cris_sim_mmapped_page
**rootp
,
901 struct cris_sim_mmapped_page
*mapp
;
903 if (len
== 0 || (len
& 8191))
906 /* Iterate over the reverse-address sorted pages until we find a page in
907 or lower than the checked area. */
908 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
909 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
915 /* Create mmapped memory. */
918 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
921 struct cris_sim_mmapped_page
*mapp
;
922 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
923 USI new_addr
= 0x40000000;
928 new_addr
= rootp
[0]->addr
+ 8192;
935 /* Which is better: return an error for this, or just round it up? */
938 /* Do a recursive call for each page in the request. */
939 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
940 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
947 mapp
!= NULL
&& mapp
->addr
> new_addr
;
949 higher_prevp
= &mapp
->prev
;
951 /* Allocate the new page, on the next higher page from the last one
952 allocated, and link in the new descriptor before previous ones. */
953 mapp
= malloc (sizeof (*mapp
));
956 return (USI
) -ENOMEM
;
958 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
962 mapp
->addr
= new_addr
;
963 mapp
->prev
= *higher_prevp
;
964 *higher_prevp
= mapp
;
969 /* Unmap one or more pages. */
972 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
975 struct cris_sim_mmapped_page
*mapp
;
976 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
983 /* Which is better: return an error for this, or just round it up? */
986 /* Loop backwards to make each call is O(1) over the number of pages
987 allocated, if we're unmapping from the high end of the pages. */
988 for (page_addr
= addr
+ len
- 8192;
991 if (unmap_pages (sd
, rootp
, page_addr
, 8192) != 0)
997 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
998 higher_prevp
= &mapp
->prev
;
1000 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1003 *higher_prevp
= mapp
->prev
;
1004 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1009 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1012 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1014 SIM_DESC sd
= CPU_STATE (current_cpu
);
1016 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1020 /* Handlers from the CGEN description that should not be called. */
1023 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1024 UINT srcreg ATTRIBUTE_UNUSED
,
1025 USI dstreg ATTRIBUTE_UNUSED
)
1031 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1032 UINT index ATTRIBUTE_UNUSED
,
1033 USI page ATTRIBUTE_UNUSED
,
1034 USI newval ATTRIBUTE_UNUSED
)
1040 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1041 UINT index ATTRIBUTE_UNUSED
,
1042 USI page ATTRIBUTE_UNUSED
)
1047 /* Swap one context for another. */
1050 schedule (SIM_CPU
*current_cpu
, int next
)
1052 /* Need to mark context-switches in the trace output. */
1053 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1054 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1055 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1058 /* Copy the current context (if there is one) to its slot. */
1059 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1060 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1061 ¤t_cpu
->cpu_data_placeholder
,
1062 current_cpu
->thread_cpu_data_size
);
1064 /* Copy the new context from its slot. */
1065 memcpy (¤t_cpu
->cpu_data_placeholder
,
1066 current_cpu
->thread_data
[next
].cpu_context
,
1067 current_cpu
->thread_cpu_data_size
);
1069 /* Update needed stuff to indicate the new context. */
1070 current_cpu
->threadno
= next
;
1072 /* Handle pending signals. */
1073 if (current_cpu
->thread_data
[next
].sigpending
1074 /* We don't run nested signal handlers. This means that pause(2)
1075 and sigsuspend(2) do not work in sighandlers, but that
1076 shouldn't be too hard a restriction. It also greatly
1077 simplifies the code. */
1078 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1082 /* See if there's really a pending, non-blocked handler. We don't
1083 queue signals, so just use the first one in ascending order. */
1084 for (sig
= 0; sig
< 64; sig
++)
1085 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1086 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1092 USI pc
= sim_pc_get (current_cpu
);
1094 /* It's simpler to save the CPU context inside the simulator
1095 than on the stack. */
1096 current_cpu
->thread_data
[next
].cpu_context_atsignal
1098 ->make_thread_cpu_data
) (current_cpu
,
1099 current_cpu
->thread_data
[next
]
1102 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1103 sp
= bfd_getl32 (regbuf
);
1105 /* Make sure we have an aligned stack. */
1108 /* Make room for the signal frame, aligned. FIXME: Check that
1109 the memory exists, map it in if absent. (BTW, should also
1110 implement on-access automatic stack allocation). */
1113 /* This isn't the same signal frame as the kernel uses, because
1114 we don't want to bother getting all registers on and off the
1117 /* First, we store the currently blocked signals. */
1119 for (i
= 0; i
< 32; i
++)
1121 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1122 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1124 for (i
= 0; i
< 31; i
++)
1126 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1127 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1129 /* Then, the actual instructions. This is CPU-specific, but we
1130 use instructions from the common subset for v10 and v32 which
1131 should be safe for the time being but could be parametrized
1133 /* MOVU.W [PC+],R9. */
1134 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1135 /* .WORD TARGET_SYS_sigreturn. */
1136 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1137 TARGET_SYS_sigreturn
);
1139 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1141 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1142 instruction. Still, it doesn't matter because v10 has no
1143 delay slot for BREAK so it will not be executed). */
1144 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1146 /* Modify registers to hold the right values for the sighandler
1147 context: updated stackpointer and return address pointing to
1148 the sigreturn stub. */
1149 bfd_putl32 (sp
, regbuf
);
1150 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1151 bfd_putl32 (sp
+ 8, regbuf
);
1152 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1155 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1157 /* Block this signal (for the duration of the sighandler). */
1158 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1160 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1161 bfd_putl32 (sig
, regbuf
);
1162 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1165 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1166 needed all this for, specifies a SA_SIGINFO call but treats it
1167 like an ordinary sighandler; only the signal number argument is
1168 inspected. To make future need to implement SA_SIGINFO
1169 correctly possible, we set the siginfo argument register to a
1170 magic (hopefully non-address) number. (NB: then, you should
1171 just need to pass the siginfo argument; it seems you probably
1172 don't need to implement the specific rt_sigreturn.) */
1173 bfd_putl32 (0xbad5161f, regbuf
);
1174 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1177 /* The third argument is unused and the kernel sets it to 0. */
1178 bfd_putl32 (0, regbuf
);
1179 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1184 /* No, there actually was no pending signal for this thread. Reset
1186 current_cpu
->thread_data
[next
].sigpending
= 0;
1190 /* Reschedule the simplest possible way until something else is absolutely
1192 - A. Find the next process (round-robin) that doesn't have at_syscall
1194 - B. If there is none, just run the next process, round-robin.
1195 - Clear at_syscall for the current process. */
1198 reschedule (SIM_CPU
*current_cpu
)
1202 /* Iterate over all thread slots, because after a few thread creations
1203 and exits, we don't know where the live ones are. */
1204 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1205 i
!= current_cpu
->threadno
;
1206 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1207 if (current_cpu
->thread_data
[i
].cpu_context
1208 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1210 schedule (current_cpu
, i
);
1214 /* Pick any next live thread. */
1215 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1216 i
!= current_cpu
->threadno
;
1217 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1218 if (current_cpu
->thread_data
[i
].cpu_context
)
1220 schedule (current_cpu
, i
);
1224 /* More than one live thread, but we couldn't find the next one? */
1228 /* Set up everything to receive (or IGN) an incoming signal to the
1232 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1235 USI pc
= sim_pc_get (current_cpu
);
1237 /* Find the thread index of the pid. */
1238 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1239 /* Apparently it's ok to send signals to zombies (so a check for
1240 current_cpu->thread_data[i].cpu_context != NULL would be
1242 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1245 switch (current_cpu
->sighandler
[sig
])
1247 case TARGET_SIG_DFL
:
1250 /* The following according to the glibc
1251 documentation. (The kernel code has non-obvious
1252 execution paths.) */
1255 case TARGET_SIGSEGV
:
1257 case TARGET_SIGABRT
:
1258 case TARGET_SIGTRAP
:
1261 case TARGET_SIGTERM
:
1263 case TARGET_SIGQUIT
:
1264 case TARGET_SIGKILL
:
1267 case TARGET_SIGALRM
:
1268 case TARGET_SIGVTALRM
:
1269 case TARGET_SIGPROF
:
1270 case TARGET_SIGSTOP
:
1272 case TARGET_SIGPIPE
:
1273 case TARGET_SIGLOST
:
1274 case TARGET_SIGXCPU
:
1275 case TARGET_SIGXFSZ
:
1276 case TARGET_SIGUSR1
:
1277 case TARGET_SIGUSR2
:
1278 sim_io_eprintf (CPU_STATE (current_cpu
),
1279 "Exiting pid %d due to signal %d\n",
1281 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1282 NULL
, pc
, sim_stopped
,
1283 sig
== TARGET_SIGABRT
1284 ? SIM_SIGABRT
: SIM_SIGILL
);
1287 /* The default for all other signals is to be ignored. */
1292 case TARGET_SIG_IGN
:
1295 case TARGET_SIGKILL
:
1296 case TARGET_SIGSTOP
:
1297 /* Can't ignore these signals. */
1298 sim_io_eprintf (CPU_STATE (current_cpu
),
1299 "Exiting pid %d due to signal %d\n",
1301 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1302 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1311 /* Mark the signal as pending, making schedule () check
1312 closer. The signal will be handled when the thread is
1313 scheduled and the signal is unblocked. */
1314 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1315 current_cpu
->thread_data
[i
].sigpending
= 1;
1320 sim_io_eprintf (CPU_STATE (current_cpu
),
1321 "Unimplemented signal: %d\n", sig
);
1322 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1323 sim_stopped
, SIM_SIGILL
);
1328 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1332 /* Make the vector and the first item, the main thread. */
1335 make_first_thread (SIM_CPU
*current_cpu
)
1337 current_cpu
->thread_data
1339 SIM_TARGET_MAX_THREADS
1340 * sizeof (current_cpu
->thread_data
[0]));
1341 current_cpu
->thread_data
[0].cpu_context
1342 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1344 ->cpu_data_placeholder
);
1345 current_cpu
->thread_data
[0].parent_threadid
= -1;
1347 /* For good measure. */
1348 if (TARGET_SIG_DFL
!= 0)
1352 /* Main function: the handler of the "break 13" syscall insn. */
1355 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1356 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1360 SIM_DESC sd
= CPU_STATE (current_cpu
);
1361 host_callback
*cb
= STATE_CALLBACK (sd
);
1363 int threadno
= current_cpu
->threadno
;
1365 current_cpu
->syscalls
++;
1367 CB_SYSCALL_INIT (&s
);
1373 if (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0)
1375 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1376 & FLAG_CRIS_MISC_PROFILE_ALL
)
1377 dump_statistics (current_cpu
);
1378 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1382 s
.p2
= (PTR
) current_cpu
;
1383 s
.read_mem
= syscall_read_mem
;
1384 s
.write_mem
= syscall_write_mem
;
1386 current_cpu_for_cb_callback
= current_cpu
;
1388 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1391 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1393 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1396 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1398 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1400 /* If the generic simulator call said ENOSYS, then let's try the
1401 ones we know ourselves.
1403 The convention is to provide *very limited* functionality on an
1404 as-needed basis, only what's covered by the test-suite, tests
1405 added when functionality changes and abort with a descriptive
1406 message for *everything* else. Where there's no test-case, we
1411 /* It's a pretty safe bet that the "old setup() system call"
1412 number will not be re-used; we can't say the same for higher
1413 numbers. We treat this simulator-generated call as "wait
1414 forever"; we re-run this insn. The wait is ended by a
1415 callback. Sanity check that this is the reason we got
1417 if (current_cpu
->thread_data
== NULL
1418 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1419 goto unimplemented_syscall
;
1421 sim_pc_set (current_cpu
, pc
);
1425 case TARGET_SYS_fcntl64
:
1426 case TARGET_SYS_fcntl
:
1431 Glibc checks stdin, stdout and stderr fd:s for
1432 close-on-exec security sanity. We just need to provide a
1433 OK return value. If we really need to have a
1434 close-on-exec flag true, we could just do a real fcntl
1440 /* F_SETFD. Just ignore attempts to set the close-on-exec
1446 /* F_GETFL. Check for the special case for open+fdopen. */
1447 if (current_cpu
->last_syscall
== TARGET_SYS_open
1448 && arg1
== current_cpu
->last_open_fd
)
1450 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1455 /* Because we can't freopen fd:s 0, 1, 2 to mean
1456 something else than stdin, stdout and stderr
1457 (sim/common/syscall.c:cb_syscall special cases fd
1458 0, 1 and 2), we know what flags that we can
1459 sanely return for these fd:s. */
1460 retval
= TARGET_O_RDONLY
;
1463 else if (arg1
== 1 || arg1
== 2)
1465 retval
= TARGET_O_WRONLY
;
1470 /* Abort for all other cases. */
1471 sim_io_eprintf (sd
, "Unimplemented %s syscall "
1472 "(fd: 0x%lx: cmd: 0x%lx arg: 0x%lx)\n",
1473 callnum
== TARGET_SYS_fcntl
1474 ? "fcntl" : "fcntl64",
1475 (unsigned long) (USI
) arg1
,
1476 (unsigned long) (USI
) arg2
,
1477 (unsigned long) (USI
) arg3
);
1478 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1484 case TARGET_SYS_uname
:
1486 /* Fill in a few constants to appease glibc. */
1487 static const char sim_utsname
[6][65] =
1497 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1498 sizeof (sim_utsname
))
1499 != sizeof (sim_utsname
))
1500 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1506 case TARGET_SYS_geteuid32
:
1507 /* We tell the truth with these. Maybe we shouldn't, but it
1508 should match the "stat" information. */
1509 retval
= geteuid ();
1512 case TARGET_SYS_getuid32
:
1516 case TARGET_SYS_getegid32
:
1517 retval
= getegid ();
1520 case TARGET_SYS_getgid32
:
1524 case TARGET_SYS_brk
:
1525 /* Most often, we just return the argument, like the Linux
1530 retval
= current_cpu
->endbrk
;
1531 else if (arg1
<= current_cpu
->endmem
)
1532 current_cpu
->endbrk
= arg1
;
1535 USI new_end
= (arg1
+ 8191) & ~8191;
1537 /* If the simulator wants to brk more than a certain very
1538 large amount, something is wrong. FIXME: Return an error
1539 or abort? Have command-line selectable? */
1540 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1542 current_cpu
->endbrk
= current_cpu
->endmem
;
1543 retval
= current_cpu
->endmem
;
1547 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1548 current_cpu
->endmem
,
1549 new_end
- current_cpu
->endmem
,
1551 current_cpu
->endbrk
= arg1
;
1552 current_cpu
->endmem
= new_end
;
1556 case TARGET_SYS_getpid
:
1557 /* Correct until CLONE_THREAD is implemented. */
1558 retval
= current_cpu
->thread_data
== NULL
1560 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1563 case TARGET_SYS_getppid
:
1564 /* Correct until CLONE_THREAD is implemented. */
1565 retval
= current_cpu
->thread_data
== NULL
1568 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1571 case TARGET_SYS_mmap2
:
1580 /* If the simulator wants to mmap more than the very large
1581 limit, something is wrong. FIXME: Return an error or
1582 abort? Have command-line selectable? */
1583 if (len
> SIM_MAX_ALLOC_CHUNK
)
1585 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1589 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1591 != (TARGET_PROT_READ
1593 | TARGET_PROT_EXEC
))
1594 && prot
!= TARGET_PROT_READ
)
1595 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1596 && flags
!= TARGET_MAP_PRIVATE
1597 && flags
!= TARGET_MAP_SHARED
)
1598 || (fd
!= (USI
) -1 && prot
!= TARGET_PROT_READ
)
1601 sim_io_eprintf (sd
, "Unimplemented mmap2 call "
1602 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1603 (unsigned long) arg1
,
1604 (unsigned long) arg2
,
1605 (unsigned long) arg3
,
1606 (unsigned long) arg4
,
1607 (unsigned long) arg5
,
1608 (unsigned long) arg6
);
1609 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1613 else if (fd
!= (USI
) -1)
1620 /* A non-aligned argument is allowed for files. */
1621 USI newlen
= (len
+ 8191) & ~8191;
1623 /* We only support read, which we should already have
1624 checked. Check again anyway. */
1625 if (prot
!= TARGET_PROT_READ
)
1629 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1632 if (newaddr
>= (USI
) -8191)
1635 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1639 /* Find the current position in the file. */
1640 s
.func
= TARGET_SYS_lseek
;
1644 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1651 /* Use the standard read callback to read in "len"
1653 s
.func
= TARGET_SYS_read
;
1657 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1660 if ((USI
) s
.result
!= len
)
1663 /* After reading, we need to go back to the previous
1664 position in the file. */
1665 s
.func
= TARGET_SYS_lseek
;
1669 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1671 if (pos
!= (USI
) s
.result
)
1679 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1680 (len
+ 8191) & ~8191);
1682 if (newaddr
>= (USI
) -8191)
1683 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1690 case TARGET_SYS_mprotect
:
1692 /* We only cover the case of linuxthreads mprotecting out its
1693 stack guard page. */
1698 if ((addr
& 8191) != 0
1700 || prot
!= TARGET_PROT_NONE
1701 || !is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1704 sim_io_eprintf (sd
, "Unimplemented mprotect call "
1705 "(0x%lx, 0x%lx, 0x%lx)\n",
1706 (unsigned long) arg1
,
1707 (unsigned long) arg2
,
1708 (unsigned long) arg3
);
1709 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1714 /* FIXME: We should account for pages like this that are
1715 "mprotected out". For now, we just tell the simulator
1716 core to remove that page from its map. */
1717 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1722 case TARGET_SYS_ioctl
:
1724 /* We support only a very limited functionality: checking
1725 stdout with TCGETS to perform the isatty function. The
1726 TCGETS ioctl isn't actually performed or the result used by
1727 an isatty () caller in a "hello, world" program; only the
1728 return value is then used. Maybe we shouldn't care about
1729 the environment of the simulator regarding isatty, but
1730 that's been working before, in the xsim simulator. */
1731 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1732 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1734 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1738 case TARGET_SYS_munmap
:
1743 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1745 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1749 case TARGET_SYS_wait4
:
1757 /* FIXME: We're not properly implementing __WCLONE, and we
1758 don't really need the special casing so we might as well
1759 make this general. */
1760 if ((!(pid
== (USI
) -1
1761 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1764 && (options
== TARGET___WCLONE
1765 || options
== TARGET___WALL
)))
1767 || current_cpu
->thread_data
== NULL
)
1769 sim_io_eprintf (sd
, "Unimplemented wait4 call "
1770 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1771 (unsigned long) arg1
,
1772 (unsigned long) arg2
,
1773 (unsigned long) arg3
,
1774 (unsigned long) arg4
);
1775 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1780 if (pid
== (USI
) -1)
1781 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1783 if (current_cpu
->thread_data
[threadno
].threadid
1784 == current_cpu
->thread_data
[i
].parent_threadid
1785 && current_cpu
->thread_data
[i
].threadid
!= 0
1786 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1788 /* A zombied child. Get the exit value and clear the
1789 zombied entry so it will be reused. */
1790 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1792 ->thread_data
[i
].exitval
);
1794 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1795 memset (¤t_cpu
->thread_data
[i
], 0,
1796 sizeof (current_cpu
->thread_data
[i
]));
1802 /* We're waiting for a specific PID. If we don't find
1803 it zombied on this run, rerun the syscall. */
1804 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1805 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1806 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1809 /* Get the exit value if the caller wants it. */
1810 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1817 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1818 memset (¤t_cpu
->thread_data
[i
], 0,
1819 sizeof (current_cpu
->thread_data
[i
]));
1824 sim_pc_set (current_cpu
, pc
);
1827 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1832 case TARGET_SYS_rt_sigaction
:
1840 __sighandler_t sa_handler;
1841 unsigned long sa_flags;
1842 void (*sa_restorer)(void);
1848 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
1849 current_cpu
->sighandler
[signum
]);
1850 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
1851 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
1853 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
1854 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
1855 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
1859 USI target_sa_handler
1860 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
1862 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
1863 USI target_sa_restorer
1864 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
1865 USI target_sa_mask_low
1866 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
1867 USI target_sa_mask_high
1868 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
1870 /* We won't interrupt a syscall so we won't restart it,
1871 but a signal(2) call ends up syscalling rt_sigaction
1872 with this flag, so we have to handle it. The
1873 sa_restorer field contains garbage when not
1874 TARGET_SA_RESTORER, so don't look at it. For the
1875 time being, we don't nest sighandlers, so we
1876 ignore the sa_mask, which simplifies things. */
1877 if ((target_sa_flags
!= 0
1878 && target_sa_flags
!= TARGET_SA_RESTART
1879 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
1880 || target_sa_handler
== 0)
1882 sim_io_eprintf (sd
, "Unimplemented rt_sigaction "
1884 "0x%lx: [0x%x, 0x%x, 0x%x, "
1887 (unsigned long) arg1
,
1888 (unsigned long) arg2
,
1889 target_sa_handler
, target_sa_flags
,
1891 target_sa_mask_low
, target_sa_mask_high
,
1892 (unsigned long) arg3
);
1893 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1897 current_cpu
->sighandler
[signum
] = target_sa_handler
;
1899 /* Because we may have unblocked signals, one may now be
1900 pending, if there are threads, that is. */
1901 if (current_cpu
->thread_data
)
1902 current_cpu
->thread_data
[threadno
].sigpending
= 1;
1908 case TARGET_SYS_mremap
:
1914 USI new_addr
= arg5
;
1917 if (new_len
== old_len
)
1918 /* The program and/or library is possibly confused but
1919 this is a valid call. Happens with ipps-1.40 on file
1922 else if (new_len
< old_len
)
1924 /* Shrinking is easy. */
1925 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1926 addr
+ new_len
, old_len
- new_len
) != 0)
1927 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1931 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1932 addr
+ old_len
, new_len
- old_len
))
1934 /* If the extension isn't mapped, we can just add it. */
1936 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1937 addr
+ old_len
, new_len
- old_len
);
1939 if (mapped_addr
> (USI
) -8192)
1940 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
1944 else if (flags
& TARGET_MREMAP_MAYMOVE
)
1946 /* Create a whole new map and copy the contents
1947 block-by-block there. We ignore the new_addr argument
1950 USI prev_addr
= addr
;
1951 USI prev_len
= old_len
;
1954 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1957 if (mapped_addr
> (USI
) -8192)
1959 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
1963 retval
= mapped_addr
;
1966 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
1968 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
1970 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
1971 mapped_addr
, 8192) != 8192)
1975 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1976 prev_addr
, prev_len
) != 0)
1980 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
1984 case TARGET_SYS_poll
:
1986 int npollfds
= arg2
;
2002 /* Check that this is the expected poll call from
2003 linuxthreads/manager.c; we don't support anything else.
2004 Remember, fd == 0 isn't supported. */
2006 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2008 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2011 || ((cb
->fstat
) (cb
, fd
, &buf
) != 0
2012 || (buf
.st_mode
& S_IFIFO
) == 0)
2013 || current_cpu
->thread_data
== NULL
)
2015 sim_io_eprintf (sd
, "Unimplemented poll syscall "
2016 "(0x%lx: [0x%x, 0x%x, x], 0x%lx, 0x%lx)\n",
2017 (unsigned long) arg1
, fd
, events
,
2018 (unsigned long) arg2
, (unsigned long) arg3
);
2019 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2025 /* Iterate over threads; find a marker that a writer is
2026 sleeping, waiting for a reader. */
2027 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2028 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2029 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2031 revents
= TARGET_POLLIN
;
2036 /* Timeout decreases with whatever time passed between the
2037 last syscall and this. That's not exactly right for the
2038 first call, but it's close enough that it isn't
2039 worthwhile to complicate matters by making that a special
2042 -= (TARGET_TIME_MS (current_cpu
)
2043 - (current_cpu
->thread_data
[threadno
].last_execution
));
2045 /* Arrange to repeat this syscall until timeout or event,
2046 decreasing timeout at each iteration. */
2047 if (timeout
> 0 && revents
== 0)
2049 bfd_byte timeout_buf
[4];
2051 bfd_putl32 (timeout
, timeout_buf
);
2052 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2053 H_GR_R12
, timeout_buf
, 4);
2054 sim_pc_set (current_cpu
, pc
);
2059 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2064 case TARGET_SYS_time
:
2066 retval
= (int) (*cb
->time
) (cb
, 0L);
2068 /* At time of this writing, CB_SYSCALL_time doesn't do the
2069 part of setting *arg1 to the return value. */
2071 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2075 case TARGET_SYS_gettimeofday
:
2078 USI ts
= TARGET_TIME (current_cpu
);
2079 USI tms
= TARGET_TIME_MS (current_cpu
);
2081 /* First dword is seconds since TARGET_EPOCH. */
2082 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2084 /* Second dword is microseconds. */
2085 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2086 (tms
% 1000) * 1000);
2090 /* Time-zone info is always cleared. */
2091 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2092 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2097 case TARGET_SYS_llseek
:
2099 /* If it fits, tweak parameters to fit the "generic" 32-bit
2100 lseek and use that. */
2108 if (!((offs_hi
== 0 && offs_lo
>= 0)
2109 || (offs_hi
== -1 && offs_lo
< 0)))
2112 "Unimplemented llseek offset,"
2113 " fd %d: 0x%x:0x%x\n",
2114 fd
, (unsigned) arg2
, (unsigned) arg3
);
2115 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2119 s
.func
= TARGET_SYS_lseek
;
2122 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2124 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2126 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2129 retval
= -s
.errcode
;
2132 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2134 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2135 s
.result
< 0 ? -1 : 0);
2140 /* This one does have a generic callback function, but at the time
2141 of this writing, cb_syscall does not have code for it, and we
2142 need target-specific code for the threads implementation
2144 case TARGET_SYS_kill
:
2151 /* At kill(2), glibc sets signal masks such that the thread
2152 machinery is initialized. Still, there is and was only
2154 if (current_cpu
->max_threadid
== 0)
2156 if (pid
!= TARGET_PID
)
2158 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2162 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2163 if (sig
== TARGET_SIGABRT
)
2164 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2165 the end-point for failing GCC test-cases. */
2166 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2170 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2171 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2175 /* This will not be reached. */
2179 retval
= deliver_signal (current_cpu
, sig
, pid
);
2183 case TARGET_SYS_rt_sigprocmask
:
2190 if (how
!= TARGET_SIG_BLOCK
2191 && how
!= TARGET_SIG_SETMASK
2192 && how
!= TARGET_SIG_UNBLOCK
)
2194 sim_io_eprintf (sd
, "Unimplemented rt_sigprocmask syscall "
2195 "(0x%x, 0x%x, 0x%x)\n", arg1
, arg2
, arg3
);
2196 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2205 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2208 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2211 /* The sigmask is kept in the per-thread data, so we may
2212 need to create the first one. */
2213 if (current_cpu
->thread_data
== NULL
)
2214 make_first_thread (current_cpu
);
2216 if (how
== TARGET_SIG_SETMASK
)
2217 for (i
= 0; i
< 64; i
++)
2218 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2220 for (i
= 0; i
< 32; i
++)
2221 if ((set_low
& (1 << i
)))
2222 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2223 = (how
!= TARGET_SIG_UNBLOCK
);
2225 for (i
= 0; i
< 31; i
++)
2226 if ((set_high
& (1 << i
)))
2227 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2228 = (how
!= TARGET_SIG_UNBLOCK
);
2230 /* The mask changed, so a signal may be unblocked for
2232 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2240 for (i
= 0; i
< 32; i
++)
2241 if (current_cpu
->thread_data
[threadno
]
2242 .sigdata
[i
+ 1].blocked
)
2244 for (i
= 0; i
< 31; i
++)
2245 if (current_cpu
->thread_data
[threadno
]
2246 .sigdata
[i
+ 33].blocked
)
2249 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2250 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2257 case TARGET_SYS_sigreturn
:
2261 int was_sigsuspended
;
2263 if (current_cpu
->thread_data
== NULL
2264 /* The CPU context is saved with the simulator data, not
2265 on the stack as in the real world. */
2266 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2269 sim_io_eprintf (sd
, "Invalid sigreturn syscall: no signal"
2271 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2272 (unsigned long) arg1
,
2273 (unsigned long) arg2
,
2274 (unsigned long) arg3
,
2275 (unsigned long) arg4
,
2276 (unsigned long) arg5
,
2277 (unsigned long) arg6
);
2278 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2283 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2285 /* Restore the sigmask, either from the stack copy made when
2286 the sighandler was called, or from the saved state
2287 specifically for sigsuspend(2). */
2288 if (was_sigsuspended
)
2290 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2291 for (i
= 0; i
< 64; i
++)
2292 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2293 = current_cpu
->thread_data
[threadno
]
2294 .sigdata
[i
].blocked_suspendsave
;
2302 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2303 H_GR_SP
, regbuf
, 4);
2304 sp
= bfd_getl32 (regbuf
);
2306 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2308 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2310 for (i
= 0; i
< 32; i
++)
2311 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2312 = (set_low
& (1 << i
)) != 0;
2313 for (i
= 0; i
< 31; i
++)
2314 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2315 = (set_high
& (1 << i
)) != 0;
2318 /* The mask changed, so a signal may be unblocked for
2320 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2322 memcpy (¤t_cpu
->cpu_data_placeholder
,
2323 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2324 current_cpu
->thread_cpu_data_size
);
2325 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2326 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2328 /* The return value must come from the saved R10. */
2329 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2330 retval
= bfd_getl32 (regbuf
);
2332 /* We must also break the "sigsuspension loop". */
2333 if (was_sigsuspended
)
2334 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2338 case TARGET_SYS_rt_sigsuspend
:
2345 sim_io_eprintf (sd
, "Unimplemented rt_sigsuspend syscall"
2346 " arguments (0x%lx, 0x%lx)\n",
2347 (unsigned long) arg1
, (unsigned long) arg2
);
2348 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2352 /* Don't change the signal mask if we're already in
2353 sigsuspend state (i.e. this syscall is a rerun). */
2354 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2357 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2360 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2364 /* Save the current sigmask and insert the user-supplied
2366 for (i
= 0; i
< 32; i
++)
2368 current_cpu
->thread_data
[threadno
]
2369 .sigdata
[i
+ 1].blocked_suspendsave
2370 = current_cpu
->thread_data
[threadno
]
2371 .sigdata
[i
+ 1].blocked
;
2373 current_cpu
->thread_data
[threadno
]
2374 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2376 for (i
= 0; i
< 31; i
++)
2378 current_cpu
->thread_data
[threadno
]
2379 .sigdata
[i
+ 33].blocked_suspendsave
2380 = current_cpu
->thread_data
[threadno
]
2381 .sigdata
[i
+ 33].blocked
;
2382 current_cpu
->thread_data
[threadno
]
2383 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2386 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2388 /* The mask changed, so a signal may be unblocked for
2390 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2393 /* Because we don't use arg1 (newsetp) when this syscall is
2394 rerun, it doesn't matter that we overwrite it with the
2395 (constant) return value. */
2396 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2397 sim_pc_set (current_cpu
, pc
);
2401 /* Add case labels here for other syscalls using the 32-bit
2402 "struct stat", provided they have a corresponding simulator
2403 function of course. */
2404 case TARGET_SYS_stat
:
2405 case TARGET_SYS_fstat
:
2407 /* As long as the infrastructure doesn't cache anything
2408 related to the stat mapping, this trick gets us a dual
2409 "struct stat"-type mapping in the least error-prone way. */
2410 const char *saved_map
= cb
->stat_map
;
2411 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2413 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2414 cb
->stat_map
= stat32_map
;
2416 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2419 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2422 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2424 cb
->stat_map
= saved_map
;
2425 cb
->syscall_map
= saved_syscall_map
;
2429 case TARGET_SYS_getcwd
:
2434 char *cwd
= xmalloc (SIM_PATHMAX
);
2435 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2438 /* FIXME: When and if we support chdir, we need something
2439 a bit more elaborate. */
2440 if (simulator_sysroot
[0] != '\0')
2443 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2444 if (strlen (cwd
) + 1 <= size
)
2446 retval
= strlen (cwd
) + 1;
2447 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2449 != (unsigned int) retval
)
2450 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2456 case TARGET_SYS_readlink
:
2461 char *pbuf
= xmalloc (SIM_PATHMAX
);
2462 char *lbuf
= xmalloc (SIM_PATHMAX
);
2463 char *lbuf_alloc
= lbuf
;
2468 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2470 strcpy (pbuf
, simulator_sysroot
);
2471 o
+= strlen (simulator_sysroot
);
2474 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2477 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2478 if (pbuf
[i
+ o
] == 0)
2482 if (i
+ o
== SIM_PATHMAX
)
2484 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2488 /* Intervene calls for certain files expected in the target
2489 proc file system. */
2490 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2491 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2494 = (STATE_PROG_ARGV (sd
) != NULL
2495 ? *STATE_PROG_ARGV (sd
) : NULL
);
2497 if (argv0
== NULL
|| *argv0
== '.')
2499 sim_io_eprintf (sd
, "Unimplemented readlink syscall "
2500 "(0x%lx: [\"%s\"], 0x%lx)\n",
2501 (unsigned long) arg1
, pbuf
,
2502 (unsigned long) arg2
);
2503 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2507 else if (*argv0
== '/')
2509 if (strncmp (simulator_sysroot
, argv0
,
2510 strlen (simulator_sysroot
)) == 0)
2511 argv0
+= strlen (simulator_sysroot
);
2513 strcpy (lbuf
, argv0
);
2514 nchars
= strlen (argv0
) + 1;
2518 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2519 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2521 if (strncmp (simulator_sysroot
, lbuf
,
2522 strlen (simulator_sysroot
)) == 0)
2523 lbuf
+= strlen (simulator_sysroot
);
2526 strcat (lbuf
, argv0
);
2527 nchars
= strlen (lbuf
) + 1;
2534 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2536 /* We trust that the readlink result returns a *relative*
2537 link, or one already adjusted for the file-path-prefix.
2538 (We can't generally tell the difference, so we go with
2539 the easiest decision; no adjustment.) */
2543 retval
= -cb_host_to_target_errno (cb
, errno
);
2547 if (bufsiz
< nchars
)
2550 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2551 buf
, nchars
) != (unsigned int) nchars
)
2552 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2561 case TARGET_SYS_sched_getscheduler
:
2565 /* FIXME: Search (other) existing threads. */
2566 if (pid
!= 0 && pid
!= TARGET_PID
)
2567 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2569 retval
= TARGET_SCHED_OTHER
;
2573 case TARGET_SYS_sched_getparam
:
2579 struct sched_param {
2583 if (pid
!= 0 && pid
!= TARGET_PID
)
2584 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2587 /* FIXME: Save scheduler setting before threads are
2589 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2590 current_cpu
->thread_data
!= NULL
2592 ->thread_data
[threadno
]
2600 case TARGET_SYS_sched_setparam
:
2605 if ((pid
!= 0 && pid
!= TARGET_PID
)
2606 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2608 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2614 case TARGET_SYS_sched_setscheduler
:
2620 if ((pid
!= 0 && pid
!= TARGET_PID
)
2621 || policy
!= TARGET_SCHED_OTHER
2622 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2624 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2626 /* FIXME: Save scheduler setting to be read in later
2627 sched_getparam calls. */
2632 case TARGET_SYS_sched_yield
:
2633 /* We reschedule to the next thread after a syscall anyway, so
2634 we don't have to do anything here than to set the return
2639 case TARGET_SYS_sched_get_priority_min
:
2640 case TARGET_SYS_sched_get_priority_max
:
2642 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2647 case TARGET_SYS_ugetrlimit
:
2649 unsigned int curlim
, maxlim
;
2650 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2652 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2658 unsigned long rlim_cur;
2659 unsigned long rlim_max;
2661 if (arg1
== TARGET_RLIMIT_NOFILE
)
2663 /* Sadly a very low limit. Better not lie, though. */
2664 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2666 else /* arg1 == TARGET_RLIMIT_STACK */
2668 maxlim
= 0xffffffff;
2671 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2672 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2677 case TARGET_SYS_setrlimit
:
2678 if (arg1
!= TARGET_RLIMIT_STACK
)
2680 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2683 /* FIXME: Save values for future ugetrlimit calls. */
2687 /* Provide a very limited subset of the sysctl functions, and
2688 abort for the rest. */
2689 case TARGET_SYS__sysctl
:
2692 struct __sysctl_args {
2699 unsigned long __unused[4];
2701 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2702 SI name0
= name
== 0
2703 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2704 SI name1
= name
== 0
2705 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2707 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2709 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2711 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2712 SI oldlen
= oldlenp
== 0
2713 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2715 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2717 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2719 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2721 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2722 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2724 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
2725 sizeof (TARGET_UTSNAME
));
2727 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
2728 TARGET_UTSNAME
, oldval
,
2730 != (unsigned int) to_write
)
2731 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2737 sim_io_eprintf (sd
, "Unimplemented _sysctl syscall "
2738 "(0x%lx: [0x%lx, 0x%lx],"
2739 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2740 (unsigned long) name
,
2741 (unsigned long) name0
,
2742 (unsigned long) name1
,
2743 (unsigned long) nlen
,
2744 (unsigned long) oldval
,
2745 (unsigned long) oldlenp
,
2746 (unsigned long) newval
,
2747 (unsigned long) newlen
);
2748 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2753 case TARGET_SYS_exit
:
2755 /* Here for all but the last thread. */
2758 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
2760 = (current_cpu
->thread_data
[threadno
].parent_threadid
2762 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
2764 /* Any children are now all orphans. */
2765 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2766 if (current_cpu
->thread_data
[i
].parent_threadid
2767 == current_cpu
->thread_data
[threadno
].threadid
)
2768 /* Make getppid(2) return 1 for them, poor little ones. */
2769 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
2771 /* Free the cpu context data. When the parent has received
2772 the exit status, we'll clear the entry too. */
2773 free (current_cpu
->thread_data
[threadno
].cpu_context
);
2774 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
2775 current_cpu
->m1threads
--;
2778 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
2780 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2784 /* Still, we may want to support non-zero exit values. */
2785 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
2788 deliver_signal (current_cpu
, exitsig
, ppid
);
2792 case TARGET_SYS_clone
:
2794 int nthreads
= current_cpu
->m1threads
+ 1;
2795 void *thread_cpu_data
;
2796 bfd_byte old_sp_buf
[4];
2798 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
2801 /* That's right, the syscall clone arguments are reversed
2802 compared to sys_clone notes in clone(2) and compared to
2803 other Linux ports (i.e. it's the same order as in the
2804 clone(2) libcall). */
2808 if (nthreads
== SIM_TARGET_MAX_THREADS
)
2810 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
2814 /* FIXME: Implement the low byte. */
2815 if ((flags
& ~TARGET_CSIGNAL
) !=
2818 | TARGET_CLONE_FILES
2819 | TARGET_CLONE_SIGHAND
)
2823 "Unimplemented clone syscall (0x%lx, 0x%lx)\n",
2824 (unsigned long) arg1
, (unsigned long) arg2
);
2825 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2829 if (current_cpu
->thread_data
== NULL
)
2830 make_first_thread (current_cpu
);
2832 /* The created thread will get the new SP and a cleared R10.
2833 Since it's created out of a copy of the old thread and we
2834 don't have a set-register-function that just take the
2835 cpu_data as a parameter, we set the childs values first,
2836 and write back or overwrite them in the parent after the
2838 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2839 H_GR_SP
, old_sp_buf
, 4);
2840 bfd_putl32 (newsp
, sp_buf
);
2841 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2842 H_GR_SP
, sp_buf
, 4);
2843 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2844 H_GR_R10
, (bfd_byte
*) zeros
, 4);
2847 ->make_thread_cpu_data
) (current_cpu
,
2848 ¤t_cpu
->cpu_data_placeholder
);
2849 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2850 H_GR_SP
, old_sp_buf
, 4);
2852 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
2854 /* Find an unused slot. After a few threads have been created
2855 and exited, the array is expected to be a bit fragmented.
2856 We don't reuse the first entry, though, that of the
2858 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
2859 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
2860 /* Don't reuse a zombied entry. */
2861 && current_cpu
->thread_data
[i
].threadid
== 0)
2864 memcpy (¤t_cpu
->thread_data
[i
],
2865 ¤t_cpu
->thread_data
[threadno
],
2866 sizeof (current_cpu
->thread_data
[i
]));
2867 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
2868 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
2869 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
2870 current_cpu
->thread_data
[i
].parent_threadid
2871 = current_cpu
->thread_data
[threadno
].threadid
;
2872 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
2873 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
2874 current_cpu
->thread_data
[i
].at_syscall
= 0;
2875 current_cpu
->thread_data
[i
].sigpending
= 0;
2876 current_cpu
->thread_data
[i
].sigsuspended
= 0;
2877 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
2878 current_cpu
->m1threads
= nthreads
;
2882 /* Better watch these in case they do something necessary. */
2883 case TARGET_SYS_socketcall
:
2884 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
2887 unimplemented_syscall
:
2889 sim_io_eprintf (sd
, "Unimplemented syscall: %d "
2890 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", callnum
,
2891 arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
2892 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2897 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
2898 if (callnum
== TARGET_SYS_open
)
2900 current_cpu
->last_open_fd
= retval
;
2901 current_cpu
->last_open_flags
= arg2
;
2903 current_cpu
->last_syscall
= callnum
;
2905 /* A system call is a rescheduling point. For the time being, we don't
2906 reschedule anywhere else. */
2907 if (current_cpu
->m1threads
!= 0
2908 /* We need to schedule off from an exiting thread that is the
2910 || (current_cpu
->thread_data
!= NULL
2911 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
2913 bfd_byte retval_buf
[4];
2915 current_cpu
->thread_data
[threadno
].last_execution
2916 = TARGET_TIME_MS (current_cpu
);
2917 bfd_putl32 (retval
, retval_buf
);
2918 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
2920 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
2921 reschedule (current_cpu
);
2923 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
2924 retval
= bfd_getl32 (retval_buf
);
2930 /* Callback from simulator write saying that the pipe at (reader, writer)
2931 is now non-empty (so the writer should wait until the pipe is empty, at
2932 least not write to this or any other pipe). Simplest is to just wait
2933 until the pipe is empty. */
2936 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
2937 int reader
, int writer
)
2939 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
2940 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
2942 /* It's the current thread: we just have to re-run the current
2943 syscall instruction (presumably "break 13") and change the syscall
2944 to the special simulator-wait code. Oh, and set a marker that
2945 we're waiting, so we can disambiguate the special call from a
2948 This function may be called multiple times between cris_pipe_empty,
2949 but we must avoid e.g. decreasing PC every time. Check fd markers
2951 if (cpu
->thread_data
== NULL
)
2953 sim_io_eprintf (CPU_STATE (cpu
),
2954 "Terminating simulation due to writing pipe rd:wr %d:%d"
2955 " from one single thread\n", reader
, writer
);
2956 sim_engine_halt (CPU_STATE (cpu
), cpu
,
2957 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
2959 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
2961 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
2962 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
2963 /* FIXME: We really shouldn't change registers other than R10 in
2964 syscalls (like R9), here or elsewhere. */
2965 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
2966 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
2970 /* Callback from simulator close or read call saying that the pipe at
2971 (reader, writer) is now empty (so the writer can write again, perhaps
2972 leave a waiting state). If there are bytes remaining, they couldn't be
2973 consumed (perhaps due to the pipe closing). */
2976 cris_pipe_empty (host_callback
*cb
,
2981 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
2982 bfd_byte r10_buf
[4];
2984 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
2986 /* We need to find the thread that waits for this pipe. */
2987 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2988 if (cpu
->thread_data
[i
].cpu_context
2989 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
2993 /* Temporarily switch to this cpu context, so we can change the
2994 PC by ordinary calls. */
2996 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
2997 &cpu
->cpu_data_placeholder
,
2998 cpu
->thread_cpu_data_size
);
2999 memcpy (&cpu
->cpu_data_placeholder
,
3000 cpu
->thread_data
[i
].cpu_context
,
3001 cpu
->thread_cpu_data_size
);
3003 /* The return value is supposed to contain the number of
3004 written bytes, which is the number of bytes requested and
3005 returned at the write call. You might think the right
3006 thing is to adjust the return-value to be only the
3007 *consumed* number of bytes, but it isn't. We're only
3008 called if the pipe buffer is fully consumed or it is being
3009 closed, possibly with remaining bytes. For the latter
3010 case, the writer is still supposed to see success for
3011 PIPE_BUF bytes (a constant which we happen to know and is
3012 unlikely to change). The return value may also be a
3013 negative number; an error value. This case is covered
3014 because "remaining" is always >= 0. */
3015 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3016 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3017 if (retval
- remaining
> TARGET_PIPE_BUF
)
3019 bfd_putl32 (retval
- remaining
, r10_buf
);
3020 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3022 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3023 memcpy (cpu
->thread_data
[i
].cpu_context
,
3024 &cpu
->cpu_data_placeholder
,
3025 cpu
->thread_cpu_data_size
);
3026 memcpy (&cpu
->cpu_data_placeholder
,
3027 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3028 cpu
->thread_cpu_data_size
);
3029 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3030 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3037 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3040 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
3042 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
3048 /* Set target-specific callback data. */
3051 cris_set_callbacks (host_callback
*cb
)
3053 /* Yeargh, have to cast away constness to avoid warnings. */
3054 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3055 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3057 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3058 parameter to cb_store_target_endian will make st_size negative.
3059 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3060 *unsigned*, and/or add syntax for signed-ness. */
3061 cb
->stat_map
= stat_map
;
3062 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3063 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3064 cb
->pipe_empty
= cris_pipe_empty
;
3065 cb
->time
= cris_time
;
3068 /* Process an address exception. */
3071 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3072 unsigned int map
, int nr_bytes
, address_word addr
,
3073 transfer_type transfer
, sim_core_signals sig
)
3075 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,