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
42 /* The verbatim values are from asm-cris/unistd.h. */
44 #define TARGET_SYS_exit 1
45 #define TARGET_SYS_read 3
46 #define TARGET_SYS_write 4
47 #define TARGET_SYS_open 5
48 #define TARGET_SYS_close 6
49 #define TARGET_SYS_unlink 10
50 #define TARGET_SYS_time 13
51 #define TARGET_SYS_lseek 19
52 #define TARGET_SYS_getpid 20
53 #define TARGET_SYS_kill 37
54 #define TARGET_SYS_rename 38
55 #define TARGET_SYS_pipe 42
56 #define TARGET_SYS_brk 45
57 #define TARGET_SYS_ioctl 54
58 #define TARGET_SYS_fcntl 55
59 #define TARGET_SYS_getppid 64
60 #define TARGET_SYS_setrlimit 75
61 #define TARGET_SYS_gettimeofday 78
62 #define TARGET_SYS_readlink 85
63 #define TARGET_SYS_munmap 91
64 #define TARGET_SYS_truncate 92
65 #define TARGET_SYS_ftruncate 93
66 #define TARGET_SYS_socketcall 102
67 #define TARGET_SYS_stat 106
68 #define TARGET_SYS_fstat 108
69 #define TARGET_SYS_wait4 114
70 #define TARGET_SYS_sigreturn 119
71 #define TARGET_SYS_clone 120
72 #define TARGET_SYS_uname 122
73 #define TARGET_SYS_mprotect 125
74 #define TARGET_SYS_llseek 140
75 #define TARGET_SYS__sysctl 149
76 #define TARGET_SYS_sched_setparam 154
77 #define TARGET_SYS_sched_getparam 155
78 #define TARGET_SYS_sched_setscheduler 156
79 #define TARGET_SYS_sched_getscheduler 157
80 #define TARGET_SYS_sched_yield 158
81 #define TARGET_SYS_sched_get_priority_max 159
82 #define TARGET_SYS_sched_get_priority_min 160
83 #define TARGET_SYS_mremap 163
84 #define TARGET_SYS_poll 168
85 #define TARGET_SYS_rt_sigaction 174
86 #define TARGET_SYS_rt_sigprocmask 175
87 #define TARGET_SYS_rt_sigsuspend 179
88 #define TARGET_SYS_getcwd 183
89 #define TARGET_SYS_ugetrlimit 191
90 #define TARGET_SYS_mmap2 192
91 #define TARGET_SYS_stat64 195
92 #define TARGET_SYS_lstat64 196
93 #define TARGET_SYS_fstat64 197
94 #define TARGET_SYS_geteuid32 201
95 #define TARGET_SYS_getuid32 199
96 #define TARGET_SYS_getegid32 202
97 #define TARGET_SYS_getgid32 200
98 #define TARGET_SYS_fcntl64 221
100 #define TARGET_PROT_READ 0x1
101 #define TARGET_PROT_WRITE 0x2
102 #define TARGET_PROT_EXEC 0x4
103 #define TARGET_PROT_NONE 0x0
105 #define TARGET_MAP_SHARED 0x01
106 #define TARGET_MAP_PRIVATE 0x02
107 #define TARGET_MAP_TYPE 0x0f
108 #define TARGET_MAP_FIXED 0x10
109 #define TARGET_MAP_ANONYMOUS 0x20
111 #define TARGET_CTL_KERN 1
112 #define TARGET_CTL_VM 2
113 #define TARGET_CTL_NET 3
114 #define TARGET_CTL_PROC 4
115 #define TARGET_CTL_FS 5
116 #define TARGET_CTL_DEBUG 6
117 #define TARGET_CTL_DEV 7
118 #define TARGET_CTL_BUS 8
119 #define TARGET_CTL_ABI 9
121 #define TARGET_CTL_KERN_VERSION 4
124 #define TARGET_MREMAP_MAYMOVE 1
125 #define TARGET_MREMAP_FIXED 2
127 #define TARGET_TCGETS 0x5401
129 #define TARGET_UTSNAME "#38 Sun Apr 1 00:00:00 MET 2001"
131 /* Seconds since the above date + 10 minutes. */
132 #define TARGET_EPOCH 986080200
134 /* Milliseconds since start of run. We use the number of syscalls to
135 avoid introducing noise in the execution time. */
136 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
138 /* Seconds as in time(2). */
139 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
141 #define TARGET_SCHED_OTHER 0
143 #define TARGET_RLIMIT_STACK 3
144 #define TARGET_RLIMIT_NOFILE 7
146 #define SIM_TARGET_MAX_THREADS 64
147 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
149 /* From linux/sched.h. */
150 #define TARGET_CSIGNAL 0x000000ff
151 #define TARGET_CLONE_VM 0x00000100
152 #define TARGET_CLONE_FS 0x00000200
153 #define TARGET_CLONE_FILES 0x00000400
154 #define TARGET_CLONE_SIGHAND 0x00000800
155 #define TARGET_CLONE_PID 0x00001000
156 #define TARGET_CLONE_PTRACE 0x00002000
157 #define TARGET_CLONE_VFORK 0x00004000
158 #define TARGET_CLONE_PARENT 0x00008000
159 #define TARGET_CLONE_THREAD 0x00010000
160 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
162 /* From asm-cris/poll.h. */
163 #define TARGET_POLLIN 1
165 /* From asm-cris/signal.h. */
166 #define TARGET_SIG_BLOCK 0
167 #define TARGET_SIG_UNBLOCK 1
168 #define TARGET_SIG_SETMASK 2
170 #define TARGET_SIG_DFL 0
171 #define TARGET_SIG_IGN 1
172 #define TARGET_SIG_ERR ((USI)-1)
174 #define TARGET_SIGHUP 1
175 #define TARGET_SIGINT 2
176 #define TARGET_SIGQUIT 3
177 #define TARGET_SIGILL 4
178 #define TARGET_SIGTRAP 5
179 #define TARGET_SIGABRT 6
180 #define TARGET_SIGIOT 6
181 #define TARGET_SIGBUS 7
182 #define TARGET_SIGFPE 8
183 #define TARGET_SIGKILL 9
184 #define TARGET_SIGUSR1 10
185 #define TARGET_SIGSEGV 11
186 #define TARGET_SIGUSR2 12
187 #define TARGET_SIGPIPE 13
188 #define TARGET_SIGALRM 14
189 #define TARGET_SIGTERM 15
190 #define TARGET_SIGSTKFLT 16
191 #define TARGET_SIGCHLD 17
192 #define TARGET_SIGCONT 18
193 #define TARGET_SIGSTOP 19
194 #define TARGET_SIGTSTP 20
195 #define TARGET_SIGTTIN 21
196 #define TARGET_SIGTTOU 22
197 #define TARGET_SIGURG 23
198 #define TARGET_SIGXCPU 24
199 #define TARGET_SIGXFSZ 25
200 #define TARGET_SIGVTALRM 26
201 #define TARGET_SIGPROF 27
202 #define TARGET_SIGWINCH 28
203 #define TARGET_SIGIO 29
204 #define TARGET_SIGPOLL SIGIO
205 /* Actually commented out in the kernel header. */
206 #define TARGET_SIGLOST 29
207 #define TARGET_SIGPWR 30
208 #define TARGET_SIGSYS 31
210 /* From include/asm-cris/signal.h. */
211 #define TARGET_SA_NOCLDSTOP 0x00000001
212 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
213 #define TARGET_SA_SIGINFO 0x00000004
214 #define TARGET_SA_ONSTACK 0x08000000
215 #define TARGET_SA_RESTART 0x10000000
216 #define TARGET_SA_NODEFER 0x40000000
217 #define TARGET_SA_RESETHAND 0x80000000
218 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
219 #define TARGET_SA_RESTORER 0x04000000
221 /* From linux/wait.h. */
222 #define TARGET_WNOHANG 1
223 #define TARGET_WUNTRACED 2
224 #define TARGET___WNOTHREAD 0x20000000
225 #define TARGET___WALL 0x40000000
226 #define TARGET___WCLONE 0x80000000
228 static const char stat_map
[] =
229 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
230 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
231 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
234 static const CB_TARGET_DEFS_MAP syscall_map
[] =
236 { CB_SYS_open
, TARGET_SYS_open
},
237 { CB_SYS_close
, TARGET_SYS_close
},
238 { CB_SYS_read
, TARGET_SYS_read
},
239 { CB_SYS_write
, TARGET_SYS_write
},
240 { CB_SYS_lseek
, TARGET_SYS_lseek
},
241 { CB_SYS_unlink
, TARGET_SYS_unlink
},
242 { CB_SYS_getpid
, TARGET_SYS_getpid
},
243 { CB_SYS_fstat
, TARGET_SYS_fstat64
},
244 { CB_SYS_lstat
, TARGET_SYS_lstat64
},
245 { CB_SYS_stat
, TARGET_SYS_stat64
},
246 { CB_SYS_pipe
, TARGET_SYS_pipe
},
247 { CB_SYS_time
, TARGET_SYS_time
},
248 { CB_SYS_rename
, TARGET_SYS_rename
},
249 { CB_SYS_truncate
, TARGET_SYS_truncate
},
250 { CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
254 /* An older, 32-bit-only stat mapping. */
255 static const char stat32_map
[] =
256 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
257 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
258 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
260 /* Map for calls using the 32-bit struct stat. Primarily used by the
261 newlib Linux mapping. */
262 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
264 { CB_SYS_fstat
, TARGET_SYS_fstat
},
265 { CB_SYS_stat
, TARGET_SYS_stat
},
269 /* Giving the true value for the running sim process will lead to
270 non-time-invariant behavior. */
271 #define TARGET_PID 42
273 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
274 we did, we'd still don't get a register number with the "16" offset. */
275 #define TARGET_SRP_REGNUM (16+11)
277 /* Extracted by applying
278 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
279 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
280 adjusting the synonyms. */
282 static const CB_TARGET_DEFS_MAP errno_map
[] =
390 { ENAMETOOLONG
, 36 },
549 { EDESTADDRREQ
, 89 },
560 #ifdef EPROTONOSUPPORT
561 { EPROTONOSUPPORT
, 93 },
563 #ifdef ESOCKTNOSUPPORT
564 { ESOCKTNOSUPPORT
, 94 },
570 { EPFNOSUPPORT
, 96 },
573 { EAFNOSUPPORT
, 97 },
579 { EADDRNOTAVAIL
, 99 },
585 { ENETUNREACH
, 101 },
591 { ECONNABORTED
, 103 },
609 { ETOOMANYREFS
, 109 },
615 { ECONNREFUSED
, 111 },
621 { EHOSTUNREACH
, 113 },
627 { EINPROGRESS
, 115 },
654 { EMEDIUMTYPE
, 124 },
659 /* Extracted by applying
660 perl -ne 'if ($_ =~ /^#define/) { split;
661 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
662 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
663 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
664 installation and removing synonyms and unnecessary items. Don't
665 forget the end-marker. */
667 /* This one we treat specially, as it's used in the fcntl syscall. */
668 #define TARGET_O_ACCMODE 3
670 static const CB_TARGET_DEFS_MAP open_map
[] = {
699 { O_NONBLOCK
, 0x800 },
711 { O_DIRECT
, 0x4000 },
714 { O_LARGEFILE
, 0x8000 },
717 { O_DIRECTORY
, 0x10000 },
720 { O_NOFOLLOW
, 0x20000 },
725 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
726 static SIM_CPU
*current_cpu_for_cb_callback
;
728 static int syscall_read_mem (host_callback
*, struct cb_syscall
*,
729 unsigned long, char *, int);
730 static int syscall_write_mem (host_callback
*, struct cb_syscall
*,
731 unsigned long, const char *, int);
732 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
734 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
736 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
738 static void dump_statistics (SIM_CPU
*current_cpu
);
739 static void make_first_thread (SIM_CPU
*current_cpu
);
741 /* Read/write functions for system call interface. */
744 syscall_read_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
745 struct cb_syscall
*sc
,
746 unsigned long taddr
, char *buf
, int bytes
)
748 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
749 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
751 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
755 syscall_write_mem (host_callback
*cb ATTRIBUTE_UNUSED
,
756 struct cb_syscall
*sc
,
757 unsigned long taddr
, const char *buf
, int bytes
)
759 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
760 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
762 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
765 /* When we risk running self-modified code (as in trampolines), this is
766 called from special-case insns. The silicon CRIS CPU:s have enough
767 cache snooping implemented making this a simulator-only issue. Tests:
768 gcc.c-torture/execute/931002-1.c execution, -O3 -g
769 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
772 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
773 USI pc ATTRIBUTE_UNUSED
)
775 SIM_DESC sd
= CPU_STATE (current_cpu
);
778 if (USING_SCACHE_P (sd
))
779 scache_flush_cpu (current_cpu
);
783 /* Output statistics at the end of a run. */
785 dump_statistics (SIM_CPU
*current_cpu
)
787 SIM_DESC sd
= CPU_STATE (current_cpu
);
788 CRIS_MISC_PROFILE
*profp
789 = CPU_CRIS_MISC_PROFILE (current_cpu
);
790 unsigned64 total
= profp
->basic_cycle_count
;
791 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
793 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
794 what's included in the "total" count only. */
795 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
796 & FLAG_CRIS_MISC_PROFILE_ALL
)
798 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
801 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
803 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
804 total
+= profp
->unaligned_mem_dword_count
;
807 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
808 textmsg
= "Schedulable clock cycles, total @: %llu\n";
810 += (profp
->memsrc_stall_count
811 + profp
->memraw_stall_count
812 + profp
->movemsrc_stall_count
813 + profp
->movemdst_stall_count
814 + profp
->mulsrc_stall_count
815 + profp
->jumpsrc_stall_count
816 + profp
->unaligned_mem_dword_count
);
819 case FLAG_CRIS_MISC_PROFILE_ALL
:
820 textmsg
= "All accounted clock cycles, total @: %llu\n";
822 += (profp
->memsrc_stall_count
823 + profp
->memraw_stall_count
824 + profp
->movemsrc_stall_count
825 + profp
->movemdst_stall_count
826 + profp
->movemaddr_stall_count
827 + profp
->mulsrc_stall_count
828 + profp
->jumpsrc_stall_count
829 + profp
->branch_stall_count
830 + profp
->jumptarget_stall_count
831 + profp
->unaligned_mem_dword_count
);
838 "Internal inconsistency at %s:%d",
840 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
841 sim_stopped
, SIM_SIGILL
);
844 /* Historically, these messages have gone to stderr, so we'll keep it
845 that way. It's also easier to then tell it from normal program
846 output. FIXME: Add redirect option like "run -e file". */
847 sim_io_eprintf (sd
, textmsg
, total
);
849 /* For v32, unaligned_mem_dword_count should always be 0. For
850 v10, memsrc_stall_count should always be 0. */
851 sim_io_eprintf (sd
, "Memory source stall cycles: %lld\n",
852 profp
->memsrc_stall_count
853 + profp
->unaligned_mem_dword_count
);
854 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %lld\n",
855 profp
->memraw_stall_count
);
856 sim_io_eprintf (sd
, "Movem source stall cycles: %lld\n",
857 profp
->movemsrc_stall_count
);
858 sim_io_eprintf (sd
, "Movem destination stall cycles: %lld\n",
859 profp
->movemdst_stall_count
);
860 sim_io_eprintf (sd
, "Movem address stall cycles: %lld\n",
861 profp
->movemaddr_stall_count
);
862 sim_io_eprintf (sd
, "Multiplication source stall cycles: %lld\n",
863 profp
->mulsrc_stall_count
);
864 sim_io_eprintf (sd
, "Jump source stall cycles: %lld\n",
865 profp
->jumpsrc_stall_count
);
866 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %lld\n",
867 profp
->branch_stall_count
);
868 sim_io_eprintf (sd
, "Jump target stall cycles: %lld\n",
869 profp
->jumptarget_stall_count
);
872 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
873 Return 1 if a overlap detected, 0 otherwise. */
876 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
877 struct cris_sim_mmapped_page
**rootp
,
880 struct cris_sim_mmapped_page
*mapp
;
882 if (len
== 0 || (len
& 8191))
885 /* Iterate over the reverse-address sorted pages until we find a page in
886 or lower than the checked area. */
887 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
888 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
894 /* Create mmapped memory. */
897 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
900 struct cris_sim_mmapped_page
*mapp
;
901 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
902 USI new_addr
= 0x40000000;
907 new_addr
= rootp
[0]->addr
+ 8192;
914 /* Which is better: return an error for this, or just round it up? */
917 /* Do a recursive call for each page in the request. */
918 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
919 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
926 mapp
!= NULL
&& mapp
->addr
> new_addr
;
928 higher_prevp
= &mapp
->prev
;
930 /* Allocate the new page, on the next higher page from the last one
931 allocated, and link in the new descriptor before previous ones. */
932 mapp
= malloc (sizeof (*mapp
));
935 return (USI
) -ENOMEM
;
937 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
941 mapp
->addr
= new_addr
;
942 mapp
->prev
= *higher_prevp
;
943 *higher_prevp
= mapp
;
948 /* Unmap one or more pages. */
951 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
954 struct cris_sim_mmapped_page
*mapp
;
955 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
962 /* Which is better: return an error for this, or just round it up? */
965 /* Loop backwards to make each call is O(1) over the number of pages
966 allocated, if we're unmapping from the high end of the pages. */
967 for (page_addr
= addr
+ len
- 8192;
970 if (unmap_pages (sd
, rootp
, page_addr
, 8192) != 0)
976 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
977 higher_prevp
= &mapp
->prev
;
979 if (mapp
== NULL
|| mapp
->addr
!= addr
)
982 *higher_prevp
= mapp
->prev
;
983 sim_core_detach (sd
, NULL
, 0, 0, addr
);
988 /* The semantic code invokes this for illegal (unrecognized) instructions. */
991 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
993 SIM_DESC sd
= CPU_STATE (current_cpu
);
995 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
999 /* Handlers from the CGEN description that should not be called. */
1002 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1003 UINT srcreg ATTRIBUTE_UNUSED
,
1004 USI dstreg ATTRIBUTE_UNUSED
)
1010 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1011 UINT index ATTRIBUTE_UNUSED
,
1012 USI page ATTRIBUTE_UNUSED
,
1013 USI newval ATTRIBUTE_UNUSED
)
1019 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1020 UINT index ATTRIBUTE_UNUSED
,
1021 USI page ATTRIBUTE_UNUSED
)
1026 /* Swap one context for another. */
1029 schedule (SIM_CPU
*current_cpu
, int next
)
1031 /* Need to mark context-switches in the trace output. */
1032 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1033 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1034 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1037 /* Copy the current context (if there is one) to its slot. */
1038 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1039 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1040 ¤t_cpu
->cpu_data_placeholder
,
1041 current_cpu
->thread_cpu_data_size
);
1043 /* Copy the new context from its slot. */
1044 memcpy (¤t_cpu
->cpu_data_placeholder
,
1045 current_cpu
->thread_data
[next
].cpu_context
,
1046 current_cpu
->thread_cpu_data_size
);
1048 /* Update needed stuff to indicate the new context. */
1049 current_cpu
->threadno
= next
;
1051 /* Handle pending signals. */
1052 if (current_cpu
->thread_data
[next
].sigpending
1053 /* We don't run nested signal handlers. This means that pause(2)
1054 and sigsuspend(2) do not work in sighandlers, but that
1055 shouldn't be too hard a restriction. It also greatly
1056 simplifies the code. */
1057 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1061 /* See if there's really a pending, non-blocked handler. We don't
1062 queue signals, so just use the first one in ascending order. */
1063 for (sig
= 0; sig
< 64; sig
++)
1064 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1065 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1071 USI pc
= sim_pc_get (current_cpu
);
1073 /* It's simpler to save the CPU context inside the simulator
1074 than on the stack. */
1075 current_cpu
->thread_data
[next
].cpu_context_atsignal
1077 ->make_thread_cpu_data
) (current_cpu
,
1078 current_cpu
->thread_data
[next
]
1081 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1082 sp
= bfd_getl32 (regbuf
);
1084 /* Make sure we have an aligned stack. */
1087 /* Make room for the signal frame, aligned. FIXME: Check that
1088 the memory exists, map it in if absent. (BTW, should also
1089 implement on-access automatic stack allocation). */
1092 /* This isn't the same signal frame as the kernel uses, because
1093 we don't want to bother getting all registers on and off the
1096 /* First, we store the currently blocked signals. */
1098 for (i
= 0; i
< 32; i
++)
1100 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1101 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1103 for (i
= 0; i
< 31; i
++)
1105 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1106 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1108 /* Then, the actual instructions. This is CPU-specific, but we
1109 use instructions from the common subset for v10 and v32 which
1110 should be safe for the time being but could be parametrized
1112 /* MOVU.W [PC+],R9. */
1113 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1114 /* .WORD TARGET_SYS_sigreturn. */
1115 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1116 TARGET_SYS_sigreturn
);
1118 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1120 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1121 instruction. Still, it doesn't matter because v10 has no
1122 delay slot for BREAK so it will not be executed). */
1123 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1125 /* Modify registers to hold the right values for the sighandler
1126 context: updated stackpointer and return address pointing to
1127 the sigreturn stub. */
1128 bfd_putl32 (sp
, regbuf
);
1129 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1130 bfd_putl32 (sp
+ 8, regbuf
);
1131 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1134 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1136 /* Block this signal (for the duration of the sighandler). */
1137 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1139 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1140 bfd_putl32 (sig
, regbuf
);
1141 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1144 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1145 needed all this for, specifies a SA_SIGINFO call but treats it
1146 like an ordinary sighandler; only the signal number argument is
1147 inspected. To make future need to implement SA_SIGINFO
1148 correctly possible, we set the siginfo argument register to a
1149 magic (hopefully non-address) number. (NB: then, you should
1150 just need to pass the siginfo argument; it seems you probably
1151 don't need to implement the specific rt_sigreturn.) */
1152 bfd_putl32 (0xbad5161f, regbuf
);
1153 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1156 /* The third argument is unused and the kernel sets it to 0. */
1157 bfd_putl32 (0, regbuf
);
1158 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1163 /* No, there actually was no pending signal for this thread. Reset
1165 current_cpu
->thread_data
[next
].sigpending
= 0;
1169 /* Reschedule the simplest possible way until something else is absolutely
1171 - A. Find the next process (round-robin) that doesn't have at_syscall
1173 - B. If there is none, just run the next process, round-robin.
1174 - Clear at_syscall for the current process. */
1177 reschedule (SIM_CPU
*current_cpu
)
1181 /* Iterate over all thread slots, because after a few thread creations
1182 and exits, we don't know where the live ones are. */
1183 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1184 i
!= current_cpu
->threadno
;
1185 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1186 if (current_cpu
->thread_data
[i
].cpu_context
1187 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1189 schedule (current_cpu
, i
);
1193 /* Pick any next live thread. */
1194 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1195 i
!= current_cpu
->threadno
;
1196 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1197 if (current_cpu
->thread_data
[i
].cpu_context
)
1199 schedule (current_cpu
, i
);
1203 /* More than one live thread, but we couldn't find the next one? */
1207 /* Set up everything to receive (or IGN) an incoming signal to the
1211 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1214 USI pc
= sim_pc_get (current_cpu
);
1216 /* Find the thread index of the pid. */
1217 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1218 /* Apparently it's ok to send signals to zombies (so a check for
1219 current_cpu->thread_data[i].cpu_context != NULL would be
1221 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1224 switch (current_cpu
->sighandler
[sig
])
1226 case TARGET_SIG_DFL
:
1229 /* The following according to the glibc
1230 documentation. (The kernel code has non-obvious
1231 execution paths.) */
1234 case TARGET_SIGSEGV
:
1236 case TARGET_SIGABRT
:
1237 case TARGET_SIGTRAP
:
1240 case TARGET_SIGTERM
:
1242 case TARGET_SIGQUIT
:
1243 case TARGET_SIGKILL
:
1246 case TARGET_SIGALRM
:
1247 case TARGET_SIGVTALRM
:
1248 case TARGET_SIGPROF
:
1249 case TARGET_SIGSTOP
:
1251 case TARGET_SIGPIPE
:
1252 case TARGET_SIGLOST
:
1253 case TARGET_SIGXCPU
:
1254 case TARGET_SIGXFSZ
:
1255 case TARGET_SIGUSR1
:
1256 case TARGET_SIGUSR2
:
1257 sim_io_eprintf (CPU_STATE (current_cpu
),
1258 "Exiting pid %d due to signal %d\n",
1260 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1261 NULL
, pc
, sim_stopped
,
1262 sig
== TARGET_SIGABRT
1263 ? SIM_SIGABRT
: SIM_SIGILL
);
1266 /* The default for all other signals is to be ignored. */
1271 case TARGET_SIG_IGN
:
1274 case TARGET_SIGKILL
:
1275 case TARGET_SIGSTOP
:
1276 /* Can't ignore these signals. */
1277 sim_io_eprintf (CPU_STATE (current_cpu
),
1278 "Exiting pid %d due to signal %d\n",
1280 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1281 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1290 /* Mark the signal as pending, making schedule () check
1291 closer. The signal will be handled when the thread is
1292 scheduled and the signal is unblocked. */
1293 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1294 current_cpu
->thread_data
[i
].sigpending
= 1;
1299 sim_io_eprintf (CPU_STATE (current_cpu
),
1300 "Unimplemented signal: %d\n", sig
);
1301 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1302 sim_stopped
, SIM_SIGILL
);
1307 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1311 /* Make the vector and the first item, the main thread. */
1314 make_first_thread (SIM_CPU
*current_cpu
)
1316 current_cpu
->thread_data
1318 SIM_TARGET_MAX_THREADS
1319 * sizeof (current_cpu
->thread_data
[0]));
1320 current_cpu
->thread_data
[0].cpu_context
1321 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1323 ->cpu_data_placeholder
);
1324 current_cpu
->thread_data
[0].parent_threadid
= -1;
1326 /* For good measure. */
1327 if (TARGET_SIG_DFL
!= 0)
1331 /* Main function: the handler of the "break 13" syscall insn. */
1334 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1335 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1339 SIM_DESC sd
= CPU_STATE (current_cpu
);
1340 host_callback
*cb
= STATE_CALLBACK (sd
);
1342 int threadno
= current_cpu
->threadno
;
1344 current_cpu
->syscalls
++;
1346 CB_SYSCALL_INIT (&s
);
1352 if (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0)
1354 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1355 & FLAG_CRIS_MISC_PROFILE_ALL
)
1356 dump_statistics (current_cpu
);
1357 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1361 s
.p2
= (PTR
) current_cpu
;
1362 s
.read_mem
= syscall_read_mem
;
1363 s
.write_mem
= syscall_write_mem
;
1365 current_cpu_for_cb_callback
= current_cpu
;
1367 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1370 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1372 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1375 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1377 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1379 /* If the generic simulator call said ENOSYS, then let's try the
1380 ones we know ourselves.
1382 The convention is to provide *very limited* functionality on an
1383 as-needed basis, only what's covered by the test-suite, tests
1384 added when functionality changes and abort with a descriptive
1385 message for *everything* else. Where there's no test-case, we
1390 /* It's a pretty safe bet that the "old setup() system call"
1391 number will not be re-used; we can't say the same for higher
1392 numbers. We treat this simulator-generated call as "wait
1393 forever"; we re-run this insn. The wait is ended by a
1394 callback. Sanity check that this is the reason we got
1396 if (current_cpu
->thread_data
== NULL
1397 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1398 goto unimplemented_syscall
;
1400 sim_pc_set (current_cpu
, pc
);
1404 case TARGET_SYS_fcntl64
:
1405 case TARGET_SYS_fcntl
:
1410 Glibc checks stdin, stdout and stderr fd:s for
1411 close-on-exec security sanity. We just need to provide a
1412 OK return value. If we really need to have a
1413 close-on-exec flag true, we could just do a real fcntl
1419 /* F_SETFD. Just ignore attempts to set the close-on-exec
1425 /* F_GETFL. Check for the special case for open+fdopen. */
1426 if (current_cpu
->last_syscall
== TARGET_SYS_open
1427 && arg1
== current_cpu
->last_open_fd
)
1429 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1433 /* Abort for all other cases. */
1435 sim_io_eprintf (sd
, "Unimplemented %s syscall "
1436 "(fd: 0x%lx: cmd: 0x%lx arg: 0x%lx)\n",
1437 callnum
== TARGET_SYS_fcntl
1438 ? "fcntl" : "fcntl64",
1439 (unsigned long) (USI
) arg1
,
1440 (unsigned long) (USI
) arg2
,
1441 (unsigned long) (USI
) arg3
);
1442 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1448 case TARGET_SYS_uname
:
1450 /* Fill in a few constants to appease glibc. */
1451 static const char sim_utsname
[6][65] =
1461 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1462 sizeof (sim_utsname
))
1463 != sizeof (sim_utsname
))
1464 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1470 case TARGET_SYS_geteuid32
:
1471 /* We tell the truth with these. Maybe we shouldn't, but it
1472 should match the "stat" information. */
1473 retval
= geteuid ();
1476 case TARGET_SYS_getuid32
:
1480 case TARGET_SYS_getegid32
:
1481 retval
= getegid ();
1484 case TARGET_SYS_getgid32
:
1488 case TARGET_SYS_brk
:
1489 /* Most often, we just return the argument, like the Linux
1494 retval
= current_cpu
->endbrk
;
1495 else if (arg1
<= current_cpu
->endmem
)
1496 current_cpu
->endbrk
= arg1
;
1499 USI new_end
= (arg1
+ 8191) & ~8191;
1501 /* If the simulator wants to brk more than a certain very
1502 large amount, something is wrong. FIXME: Return an error
1503 or abort? Have command-line selectable? */
1504 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1506 current_cpu
->endbrk
= current_cpu
->endmem
;
1507 retval
= current_cpu
->endmem
;
1511 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1512 current_cpu
->endmem
,
1513 new_end
- current_cpu
->endmem
,
1515 current_cpu
->endbrk
= arg1
;
1516 current_cpu
->endmem
= new_end
;
1520 case TARGET_SYS_getpid
:
1521 /* Correct until CLONE_THREAD is implemented. */
1522 retval
= current_cpu
->thread_data
== NULL
1524 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1527 case TARGET_SYS_getppid
:
1528 /* Correct until CLONE_THREAD is implemented. */
1529 retval
= current_cpu
->thread_data
== NULL
1532 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1535 case TARGET_SYS_mmap2
:
1544 /* If the simulator wants to mmap more than the very large
1545 limit, something is wrong. FIXME: Return an error or
1546 abort? Have command-line selectable? */
1547 if (len
> SIM_MAX_ALLOC_CHUNK
)
1549 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1553 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1555 != (TARGET_PROT_READ
1557 | TARGET_PROT_EXEC
))
1558 && prot
!= TARGET_PROT_READ
)
1559 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1560 && flags
!= TARGET_MAP_PRIVATE
1561 && flags
!= TARGET_MAP_SHARED
)
1562 || (fd
!= (USI
) -1 && prot
!= TARGET_PROT_READ
)
1565 sim_io_eprintf (sd
, "Unimplemented mmap2 call "
1566 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1567 (unsigned long) arg1
,
1568 (unsigned long) arg2
,
1569 (unsigned long) arg3
,
1570 (unsigned long) arg4
,
1571 (unsigned long) arg5
,
1572 (unsigned long) arg6
);
1573 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1577 else if (fd
!= (USI
) -1)
1584 /* A non-aligned argument is allowed for files. */
1585 USI newlen
= (len
+ 8191) & ~8191;
1587 /* We only support read, which we should already have
1588 checked. Check again anyway. */
1589 if (prot
!= TARGET_PROT_READ
)
1593 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1596 if (newaddr
>= (USI
) -8191)
1599 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1603 /* Find the current position in the file. */
1604 s
.func
= TARGET_SYS_lseek
;
1608 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1615 /* Use the standard read callback to read in "len"
1617 s
.func
= TARGET_SYS_read
;
1621 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1624 if ((USI
) s
.result
!= len
)
1627 /* After reading, we need to go back to the previous
1628 position in the file. */
1629 s
.func
= TARGET_SYS_lseek
;
1633 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1635 if (pos
!= (USI
) s
.result
)
1643 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1644 (len
+ 8191) & ~8191);
1646 if (newaddr
>= (USI
) -8191)
1647 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1654 case TARGET_SYS_mprotect
:
1656 /* We only cover the case of linuxthreads mprotecting out its
1657 stack guard page. */
1662 if ((addr
& 8191) != 0
1664 || prot
!= TARGET_PROT_NONE
1665 || !is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1668 sim_io_eprintf (sd
, "Unimplemented mprotect call "
1669 "(0x%lx, 0x%lx, 0x%lx)\n",
1670 (unsigned long) arg1
,
1671 (unsigned long) arg2
,
1672 (unsigned long) arg3
);
1673 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1678 /* FIXME: We should account for pages like this that are
1679 "mprotected out". For now, we just tell the simulator
1680 core to remove that page from its map. */
1681 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1686 case TARGET_SYS_ioctl
:
1688 /* We support only a very limited functionality: checking
1689 stdout with TCGETS to perform the isatty function. The
1690 TCGETS ioctl isn't actually performed or the result used by
1691 an isatty () caller in a "hello, world" program; only the
1692 return value is then used. Maybe we shouldn't care about
1693 the environment of the simulator regarding isatty, but
1694 that's been working before, in the xsim simulator. */
1695 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1696 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1698 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1702 case TARGET_SYS_munmap
:
1707 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1709 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1713 case TARGET_SYS_wait4
:
1721 /* FIXME: We're not properly implementing __WCLONE, and we
1722 don't really need the special casing so we might as well
1723 make this general. */
1724 if ((!(pid
== (USI
) -1
1725 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1728 && (options
== TARGET___WCLONE
1729 || options
== TARGET___WALL
)))
1731 || current_cpu
->thread_data
== NULL
)
1733 sim_io_eprintf (sd
, "Unimplemented wait4 call "
1734 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1735 (unsigned long) arg1
,
1736 (unsigned long) arg2
,
1737 (unsigned long) arg3
,
1738 (unsigned long) arg4
);
1739 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1744 if (pid
== (USI
) -1)
1745 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1747 if (current_cpu
->thread_data
[threadno
].threadid
1748 == current_cpu
->thread_data
[i
].parent_threadid
1749 && current_cpu
->thread_data
[i
].threadid
!= 0
1750 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1752 /* A zombied child. Get the exit value and clear the
1753 zombied entry so it will be reused. */
1754 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1756 ->thread_data
[i
].exitval
);
1758 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1759 memset (¤t_cpu
->thread_data
[i
], 0,
1760 sizeof (current_cpu
->thread_data
[i
]));
1766 /* We're waiting for a specific PID. If we don't find
1767 it zombied on this run, rerun the syscall. */
1768 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1769 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1770 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1773 /* Get the exit value if the caller wants it. */
1774 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1781 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1782 memset (¤t_cpu
->thread_data
[i
], 0,
1783 sizeof (current_cpu
->thread_data
[i
]));
1788 sim_pc_set (current_cpu
, pc
);
1791 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1796 case TARGET_SYS_rt_sigaction
:
1804 __sighandler_t sa_handler;
1805 unsigned long sa_flags;
1806 void (*sa_restorer)(void);
1812 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
1813 current_cpu
->sighandler
[signum
]);
1814 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
1815 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
1817 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
1818 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
1819 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
1823 USI target_sa_handler
1824 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
1826 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
1827 USI target_sa_restorer
1828 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
1829 USI target_sa_mask_low
1830 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
1831 USI target_sa_mask_high
1832 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
1834 /* We won't interrupt a syscall so we won't restart it,
1835 but a signal(2) call ends up syscalling rt_sigaction
1836 with this flag, so we have to handle it. The
1837 sa_restorer field contains garbage when not
1838 TARGET_SA_RESTORER, so don't look at it. For the
1839 time being, we don't nest sighandlers, so we
1840 ignore the sa_mask, which simplifies things. */
1841 if ((target_sa_flags
!= 0
1842 && target_sa_flags
!= TARGET_SA_RESTART
1843 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
1844 || target_sa_handler
== 0)
1846 sim_io_eprintf (sd
, "Unimplemented rt_sigaction "
1848 "0x%lx: [0x%x, 0x%x, 0x%x, "
1851 (unsigned long) arg1
,
1852 (unsigned long) arg2
,
1853 target_sa_handler
, target_sa_flags
,
1855 target_sa_mask_low
, target_sa_mask_high
,
1856 (unsigned long) arg3
);
1857 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
1861 current_cpu
->sighandler
[signum
] = target_sa_handler
;
1863 /* Because we may have unblocked signals, one may now be
1864 pending, if there are threads, that is. */
1865 if (current_cpu
->thread_data
)
1866 current_cpu
->thread_data
[threadno
].sigpending
= 1;
1872 case TARGET_SYS_mremap
:
1878 USI new_addr
= arg5
;
1881 if (new_len
== old_len
)
1882 /* The program and/or library is possibly confused but
1883 this is a valid call. Happens with ipps-1.40 on file
1886 else if (new_len
< old_len
)
1888 /* Shrinking is easy. */
1889 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1890 addr
+ new_len
, old_len
- new_len
) != 0)
1891 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1895 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1896 addr
+ old_len
, new_len
- old_len
))
1898 /* If the extension isn't mapped, we can just add it. */
1900 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1901 addr
+ old_len
, new_len
- old_len
);
1903 if (mapped_addr
> (USI
) -8192)
1904 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
1908 else if (flags
& TARGET_MREMAP_MAYMOVE
)
1910 /* Create a whole new map and copy the contents
1911 block-by-block there. We ignore the new_addr argument
1914 USI prev_addr
= addr
;
1915 USI prev_len
= old_len
;
1918 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1921 if (mapped_addr
> (USI
) -8192)
1923 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
1927 retval
= mapped_addr
;
1930 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
1932 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
1934 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
1935 mapped_addr
, 8192) != 8192)
1939 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1940 prev_addr
, prev_len
) != 0)
1944 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
1948 case TARGET_SYS_poll
:
1950 int npollfds
= arg2
;
1966 /* Check that this is the expected poll call from
1967 linuxthreads/manager.c; we don't support anything else.
1968 Remember, fd == 0 isn't supported. */
1970 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
1972 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
1975 || ((cb
->fstat
) (cb
, fd
, &buf
) != 0
1976 || (buf
.st_mode
& S_IFIFO
) == 0)
1977 || current_cpu
->thread_data
== NULL
)
1979 sim_io_eprintf (sd
, "Unimplemented poll syscall "
1980 "(0x%lx: [0x%x, 0x%x, x], 0x%lx, 0x%lx)\n",
1981 (unsigned long) arg1
, fd
, events
,
1982 (unsigned long) arg2
, (unsigned long) arg3
);
1983 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1989 /* Iterate over threads; find a marker that a writer is
1990 sleeping, waiting for a reader. */
1991 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1992 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
1993 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
1995 revents
= TARGET_POLLIN
;
2000 /* Timeout decreases with whatever time passed between the
2001 last syscall and this. That's not exactly right for the
2002 first call, but it's close enough that it isn't
2003 worthwhile to complicate matters by making that a special
2006 -= (TARGET_TIME_MS (current_cpu
)
2007 - (current_cpu
->thread_data
[threadno
].last_execution
));
2009 /* Arrange to repeat this syscall until timeout or event,
2010 decreasing timeout at each iteration. */
2011 if (timeout
> 0 && revents
== 0)
2013 bfd_byte timeout_buf
[4];
2015 bfd_putl32 (timeout
, timeout_buf
);
2016 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2017 H_GR_R12
, timeout_buf
, 4);
2018 sim_pc_set (current_cpu
, pc
);
2023 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2028 case TARGET_SYS_gettimeofday
:
2031 USI ts
= TARGET_TIME (current_cpu
);
2032 USI tms
= TARGET_TIME_MS (current_cpu
);
2034 /* First dword is seconds since TARGET_EPOCH. */
2035 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2037 /* Second dword is microseconds. */
2038 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2039 (tms
% 1000) * 1000);
2043 /* Time-zone info is always cleared. */
2044 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2045 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2050 case TARGET_SYS_llseek
:
2052 /* If it fits, tweak parameters to fit the "generic" 32-bit
2053 lseek and use that. */
2061 if (!((offs_hi
== 0 && offs_lo
>= 0)
2062 || (offs_hi
== -1 && offs_lo
< 0)))
2065 "Unimplemented llseek offset,"
2066 " fd %d: 0x%x:0x%x\n",
2067 fd
, (unsigned) arg2
, (unsigned) arg3
);
2068 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2072 s
.func
= TARGET_SYS_lseek
;
2075 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2077 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2079 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2082 retval
= -s
.errcode
;
2085 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2087 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2088 s
.result
< 0 ? -1 : 0);
2093 /* This one does have a generic callback function, but at the time
2094 of this writing, cb_syscall does not have code for it, and we
2095 need target-specific code for the threads implementation
2097 case TARGET_SYS_kill
:
2104 /* At kill(2), glibc sets signal masks such that the thread
2105 machinery is initialized. Still, there is and was only
2107 if (current_cpu
->max_threadid
== 0)
2109 if (pid
!= TARGET_PID
)
2111 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2115 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2116 if (sig
== TARGET_SIGABRT
)
2117 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2118 the end-point for failing GCC test-cases. */
2119 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2123 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2124 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2128 /* This will not be reached. */
2132 retval
= deliver_signal (current_cpu
, sig
, pid
);
2136 case TARGET_SYS_rt_sigprocmask
:
2143 if (how
!= TARGET_SIG_BLOCK
2144 && how
!= TARGET_SIG_SETMASK
2145 && how
!= TARGET_SIG_UNBLOCK
)
2147 sim_io_eprintf (sd
, "Unimplemented rt_sigprocmask syscall "
2148 "(0x%x, 0x%x, 0x%x)\n", arg1
, arg2
, arg3
);
2149 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2158 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2161 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2164 /* The sigmask is kept in the per-thread data, so we may
2165 need to create the first one. */
2166 if (current_cpu
->thread_data
== NULL
)
2167 make_first_thread (current_cpu
);
2169 if (how
== TARGET_SIG_SETMASK
)
2170 for (i
= 0; i
< 64; i
++)
2171 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2173 for (i
= 0; i
< 32; i
++)
2174 if ((set_low
& (1 << i
)))
2175 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2176 = (how
!= TARGET_SIG_UNBLOCK
);
2178 for (i
= 0; i
< 31; i
++)
2179 if ((set_high
& (1 << i
)))
2180 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2181 = (how
!= TARGET_SIG_UNBLOCK
);
2183 /* The mask changed, so a signal may be unblocked for
2185 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2193 for (i
= 0; i
< 32; i
++)
2194 if (current_cpu
->thread_data
[threadno
]
2195 .sigdata
[i
+ 1].blocked
)
2197 for (i
= 0; i
< 31; i
++)
2198 if (current_cpu
->thread_data
[threadno
]
2199 .sigdata
[i
+ 33].blocked
)
2202 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2203 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2210 case TARGET_SYS_sigreturn
:
2214 int was_sigsuspended
;
2216 if (current_cpu
->thread_data
== NULL
2217 /* The CPU context is saved with the simulator data, not
2218 on the stack as in the real world. */
2219 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2222 sim_io_eprintf (sd
, "Invalid sigreturn syscall: no signal"
2224 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2225 (unsigned long) arg1
,
2226 (unsigned long) arg2
,
2227 (unsigned long) arg3
,
2228 (unsigned long) arg4
,
2229 (unsigned long) arg5
,
2230 (unsigned long) arg6
);
2231 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2236 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2238 /* Restore the sigmask, either from the stack copy made when
2239 the sighandler was called, or from the saved state
2240 specifically for sigsuspend(2). */
2241 if (was_sigsuspended
)
2243 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2244 for (i
= 0; i
< 64; i
++)
2245 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2246 = current_cpu
->thread_data
[threadno
]
2247 .sigdata
[i
].blocked_suspendsave
;
2255 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2256 H_GR_SP
, regbuf
, 4);
2257 sp
= bfd_getl32 (regbuf
);
2259 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2261 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2263 for (i
= 0; i
< 32; i
++)
2264 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2265 = (set_low
& (1 << i
)) != 0;
2266 for (i
= 0; i
< 31; i
++)
2267 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2268 = (set_high
& (1 << i
)) != 0;
2271 /* The mask changed, so a signal may be unblocked for
2273 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2275 memcpy (¤t_cpu
->cpu_data_placeholder
,
2276 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2277 current_cpu
->thread_cpu_data_size
);
2278 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2279 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2281 /* The return value must come from the saved R10. */
2282 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2283 retval
= bfd_getl32 (regbuf
);
2285 /* We must also break the "sigsuspension loop". */
2286 if (was_sigsuspended
)
2287 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2291 case TARGET_SYS_rt_sigsuspend
:
2298 sim_io_eprintf (sd
, "Unimplemented rt_sigsuspend syscall"
2299 " arguments (0x%lx, 0x%lx)\n",
2300 (unsigned long) arg1
, (unsigned long) arg2
);
2301 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2305 /* Don't change the signal mask if we're already in
2306 sigsuspend state (i.e. this syscall is a rerun). */
2307 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2310 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2313 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2317 /* Save the current sigmask and insert the user-supplied
2319 for (i
= 0; i
< 32; i
++)
2321 current_cpu
->thread_data
[threadno
]
2322 .sigdata
[i
+ 1].blocked_suspendsave
2323 = current_cpu
->thread_data
[threadno
]
2324 .sigdata
[i
+ 1].blocked
;
2326 current_cpu
->thread_data
[threadno
]
2327 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2329 for (i
= 0; i
< 31; i
++)
2331 current_cpu
->thread_data
[threadno
]
2332 .sigdata
[i
+ 33].blocked_suspendsave
2333 = current_cpu
->thread_data
[threadno
]
2334 .sigdata
[i
+ 33].blocked
;
2335 current_cpu
->thread_data
[threadno
]
2336 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2339 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2341 /* The mask changed, so a signal may be unblocked for
2343 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2346 /* Because we don't use arg1 (newsetp) when this syscall is
2347 rerun, it doesn't matter that we overwrite it with the
2348 (constant) return value. */
2349 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2350 sim_pc_set (current_cpu
, pc
);
2354 /* Add case labels here for other syscalls using the 32-bit
2355 "struct stat", provided they have a corresponding simulator
2356 function of course. */
2357 case TARGET_SYS_stat
:
2358 case TARGET_SYS_fstat
:
2360 /* As long as the infrastructure doesn't cache anything
2361 related to the stat mapping, this trick gets us a dual
2362 "struct stat"-type mapping in the least error-prone way. */
2363 const char *saved_map
= cb
->stat_map
;
2364 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2366 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2367 cb
->stat_map
= stat32_map
;
2369 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2372 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2375 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2377 cb
->stat_map
= saved_map
;
2378 cb
->syscall_map
= saved_syscall_map
;
2382 case TARGET_SYS_getcwd
:
2387 char *cwd
= xmalloc (MAXPATHLEN
);
2388 if (cwd
!= getcwd (cwd
, MAXPATHLEN
))
2391 /* FIXME: When and if we support chdir, we need something
2392 a bit more elaborate. */
2393 if (simulator_sysroot
[0] != '\0')
2396 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2397 if (strlen (cwd
) + 1 <= size
)
2399 retval
= strlen (cwd
) + 1;
2400 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2402 != (unsigned int) retval
)
2403 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2409 case TARGET_SYS_readlink
:
2414 char *pbuf
= xmalloc (MAXPATHLEN
);
2415 char *lbuf
= xmalloc (MAXPATHLEN
);
2416 char *lbuf_alloc
= lbuf
;
2421 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2423 strcpy (pbuf
, simulator_sysroot
);
2424 o
+= strlen (simulator_sysroot
);
2427 for (i
= 0; i
+ o
< MAXPATHLEN
; i
++)
2430 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2431 if (pbuf
[i
+ o
] == 0)
2435 if (i
+ o
== MAXPATHLEN
)
2437 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2441 /* Intervene calls for certain files expected in the target
2442 proc file system. */
2443 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2444 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2447 = (STATE_PROG_ARGV (sd
) != NULL
2448 ? *STATE_PROG_ARGV (sd
) : NULL
);
2450 if (argv0
== NULL
|| *argv0
== '.')
2452 sim_io_eprintf (sd
, "Unimplemented readlink syscall "
2453 "(0x%lx: [\"%s\"], 0x%lx)\n",
2454 (unsigned long) arg1
, pbuf
,
2455 (unsigned long) arg2
);
2456 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2460 else if (*argv0
== '/')
2462 if (strncmp (simulator_sysroot
, argv0
,
2463 strlen (simulator_sysroot
)) == 0)
2464 argv0
+= strlen (simulator_sysroot
);
2466 strcpy (lbuf
, argv0
);
2467 nchars
= strlen (argv0
) + 1;
2471 if (getcwd (lbuf
, MAXPATHLEN
) != NULL
2472 && strlen (lbuf
) + 2 + strlen (argv0
) < MAXPATHLEN
)
2474 if (strncmp (simulator_sysroot
, lbuf
,
2475 strlen (simulator_sysroot
)) == 0)
2476 lbuf
+= strlen (simulator_sysroot
);
2479 strcat (lbuf
, argv0
);
2480 nchars
= strlen (lbuf
) + 1;
2487 nchars
= readlink (pbuf
, lbuf
, MAXPATHLEN
);
2489 /* We trust that the readlink result returns a *relative*
2490 link, or one already adjusted for the file-path-prefix.
2491 (We can't generally tell the difference, so we go with
2492 the easiest decision; no adjustment.) */
2496 retval
= -cb_host_to_target_errno (cb
, errno
);
2500 if (bufsiz
< nchars
)
2503 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2504 buf
, nchars
) != (unsigned int) nchars
)
2505 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2514 case TARGET_SYS_sched_getscheduler
:
2518 /* FIXME: Search (other) existing threads. */
2519 if (pid
!= 0 && pid
!= TARGET_PID
)
2520 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2522 retval
= TARGET_SCHED_OTHER
;
2526 case TARGET_SYS_sched_getparam
:
2532 struct sched_param {
2536 if (pid
!= 0 && pid
!= TARGET_PID
)
2537 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2540 /* FIXME: Save scheduler setting before threads are
2542 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2543 current_cpu
->thread_data
!= NULL
2545 ->thread_data
[threadno
]
2553 case TARGET_SYS_sched_setparam
:
2558 if ((pid
!= 0 && pid
!= TARGET_PID
)
2559 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2561 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2567 case TARGET_SYS_sched_setscheduler
:
2573 if ((pid
!= 0 && pid
!= TARGET_PID
)
2574 || policy
!= TARGET_SCHED_OTHER
2575 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2577 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2579 /* FIXME: Save scheduler setting to be read in later
2580 sched_getparam calls. */
2585 case TARGET_SYS_sched_yield
:
2586 /* We reschedule to the next thread after a syscall anyway, so
2587 we don't have to do anything here than to set the return
2592 case TARGET_SYS_sched_get_priority_min
:
2593 case TARGET_SYS_sched_get_priority_max
:
2595 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2600 case TARGET_SYS_ugetrlimit
:
2602 unsigned int curlim
, maxlim
;
2603 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2605 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2611 unsigned long rlim_cur;
2612 unsigned long rlim_max;
2614 if (arg1
== TARGET_RLIMIT_NOFILE
)
2616 /* Sadly a very low limit. Better not lie, though. */
2617 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2619 else /* arg1 == TARGET_RLIMIT_STACK */
2621 maxlim
= 0xffffffff;
2624 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2625 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2630 case TARGET_SYS_setrlimit
:
2631 if (arg1
!= TARGET_RLIMIT_STACK
)
2633 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2636 /* FIXME: Save values for future ugetrlimit calls. */
2640 /* Provide a very limited subset of the sysctl functions, and
2641 abort for the rest. */
2642 case TARGET_SYS__sysctl
:
2645 struct __sysctl_args {
2652 unsigned long __unused[4];
2654 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2655 SI name0
= name
== 0
2656 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2657 SI name1
= name
== 0
2658 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2660 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2662 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2664 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2665 SI oldlen
= oldlenp
== 0
2666 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2668 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2670 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2672 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2674 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2675 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2677 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
2678 sizeof (TARGET_UTSNAME
));
2680 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
2681 TARGET_UTSNAME
, oldval
,
2683 != (unsigned int) to_write
)
2684 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2690 sim_io_eprintf (sd
, "Unimplemented _sysctl syscall "
2691 "(0x%lx: [0x%lx, 0x%lx],"
2692 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2693 (unsigned long) name
,
2694 (unsigned long) name0
,
2695 (unsigned long) name1
,
2696 (unsigned long) nlen
,
2697 (unsigned long) oldval
,
2698 (unsigned long) oldlenp
,
2699 (unsigned long) newval
,
2700 (unsigned long) newlen
);
2701 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2706 case TARGET_SYS_exit
:
2708 /* Here for all but the last thread. */
2711 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
2713 = (current_cpu
->thread_data
[threadno
].parent_threadid
2715 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
2717 /* Any children are now all orphans. */
2718 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2719 if (current_cpu
->thread_data
[i
].parent_threadid
2720 == current_cpu
->thread_data
[threadno
].threadid
)
2721 /* Make getppid(2) return 1 for them, poor little ones. */
2722 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
2724 /* Free the cpu context data. When the parent has received
2725 the exit status, we'll clear the entry too. */
2726 free (current_cpu
->thread_data
[threadno
].cpu_context
);
2727 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
2728 current_cpu
->m1threads
--;
2731 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
2733 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2737 /* Still, we may want to support non-zero exit values. */
2738 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
2741 deliver_signal (current_cpu
, exitsig
, ppid
);
2745 case TARGET_SYS_clone
:
2747 int nthreads
= current_cpu
->m1threads
+ 1;
2748 void *thread_cpu_data
;
2749 bfd_byte old_sp_buf
[4];
2751 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
2754 /* That's right, the syscall clone arguments are reversed
2755 compared to sys_clone notes in clone(2) and compared to
2756 other Linux ports (i.e. it's the same order as in the
2757 clone(2) libcall). */
2761 if (nthreads
== SIM_TARGET_MAX_THREADS
)
2763 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
2767 /* FIXME: Implement the low byte. */
2768 if ((flags
& ~TARGET_CSIGNAL
) !=
2771 | TARGET_CLONE_FILES
2772 | TARGET_CLONE_SIGHAND
)
2776 "Unimplemented clone syscall (0x%lx, 0x%lx)\n",
2777 (unsigned long) arg1
, (unsigned long) arg2
);
2778 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2782 if (current_cpu
->thread_data
== NULL
)
2783 make_first_thread (current_cpu
);
2785 /* The created thread will get the new SP and a cleared R10.
2786 Since it's created out of a copy of the old thread and we
2787 don't have a set-register-function that just take the
2788 cpu_data as a parameter, we set the childs values first,
2789 and write back or overwrite them in the parent after the
2791 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2792 H_GR_SP
, old_sp_buf
, 4);
2793 bfd_putl32 (newsp
, sp_buf
);
2794 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2795 H_GR_SP
, sp_buf
, 4);
2796 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2797 H_GR_R10
, (bfd_byte
*) zeros
, 4);
2800 ->make_thread_cpu_data
) (current_cpu
,
2801 ¤t_cpu
->cpu_data_placeholder
);
2802 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2803 H_GR_SP
, old_sp_buf
, 4);
2805 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
2807 /* Find an unused slot. After a few threads have been created
2808 and exited, the array is expected to be a bit fragmented.
2809 We don't reuse the first entry, though, that of the
2811 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
2812 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
2813 /* Don't reuse a zombied entry. */
2814 && current_cpu
->thread_data
[i
].threadid
== 0)
2817 memcpy (¤t_cpu
->thread_data
[i
],
2818 ¤t_cpu
->thread_data
[threadno
],
2819 sizeof (current_cpu
->thread_data
[i
]));
2820 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
2821 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
2822 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
2823 current_cpu
->thread_data
[i
].parent_threadid
2824 = current_cpu
->thread_data
[threadno
].threadid
;
2825 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
2826 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
2827 current_cpu
->thread_data
[i
].at_syscall
= 0;
2828 current_cpu
->thread_data
[i
].sigpending
= 0;
2829 current_cpu
->thread_data
[i
].sigsuspended
= 0;
2830 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
2831 current_cpu
->m1threads
= nthreads
;
2835 /* Better watch these in case they do something necessary. */
2836 case TARGET_SYS_socketcall
:
2837 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
2840 unimplemented_syscall
:
2842 sim_io_eprintf (sd
, "Unimplemented syscall: %d "
2843 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", callnum
,
2844 arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
2845 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2850 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
2851 if (callnum
== TARGET_SYS_open
)
2853 current_cpu
->last_open_fd
= retval
;
2854 current_cpu
->last_open_flags
= arg2
;
2856 current_cpu
->last_syscall
= callnum
;
2858 /* A system call is a rescheduling point. For the time being, we don't
2859 reschedule anywhere else. */
2860 if (current_cpu
->m1threads
!= 0
2861 /* We need to schedule off from an exiting thread that is the
2863 || (current_cpu
->thread_data
!= NULL
2864 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
2866 bfd_byte retval_buf
[4];
2868 current_cpu
->thread_data
[threadno
].last_execution
2869 = TARGET_TIME_MS (current_cpu
);
2870 bfd_putl32 (retval
, retval_buf
);
2871 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
2873 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
2874 reschedule (current_cpu
);
2876 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
2877 retval
= bfd_getl32 (retval_buf
);
2883 /* Callback from simulator write saying that the pipe at (reader, writer)
2884 is now non-empty (so the writer should wait until the pipe is empty, at
2885 least not write to this or any other pipe). Simplest is to just wait
2886 until the pipe is empty. */
2889 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
2890 int reader
, int writer
)
2892 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
2893 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
2895 /* It's the current thread: we just have to re-run the current
2896 syscall instruction (presumably "break 13") and change the syscall
2897 to the special simulator-wait code. Oh, and set a marker that
2898 we're waiting, so we can disambiguate the special call from a
2901 This function may be called multiple times between cris_pipe_empty,
2902 but we must avoid e.g. decreasing PC every time. Check fd markers
2904 if (cpu
->thread_data
== NULL
)
2906 sim_io_eprintf (CPU_STATE (cpu
),
2907 "Terminating simulation due to writing pipe rd:wr %d:%d"
2908 " from one single thread\n", reader
, writer
);
2909 sim_engine_halt (CPU_STATE (cpu
), cpu
,
2910 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
2912 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
2914 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
2915 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
2916 /* FIXME: We really shouldn't change registers other than R10 in
2917 syscalls (like R9), here or elsewhere. */
2918 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
2919 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
2923 /* Callback from simulator close or read call saying that the pipe at
2924 (reader, writer) is now empty (so the writer can write again, perhaps
2925 leave a waiting state). If there are bytes remaining, they couldn't be
2926 consumed (perhaps due to the pipe closing). */
2929 cris_pipe_empty (host_callback
*cb
,
2930 int reader ATTRIBUTE_UNUSED
,
2934 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
2935 bfd_byte r10_buf
[4];
2936 int remaining
= cb
->pipe_buffer
[writer
].size
;
2938 /* We need to find the thread that waits for this pipe. */
2939 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2940 if (cpu
->thread_data
[i
].cpu_context
2941 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
2944 /* Temporarily switch to this cpu context, so we can change the
2945 PC by ordinary calls. */
2947 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
2948 &cpu
->cpu_data_placeholder
,
2949 cpu
->thread_cpu_data_size
);
2950 memcpy (&cpu
->cpu_data_placeholder
,
2951 cpu
->thread_data
[i
].cpu_context
,
2952 cpu
->thread_cpu_data_size
);
2954 /* The return value is supposed to contain the number of written
2955 bytes, which is the number of bytes requested and returned at
2956 the write call. We subtract the remaining bytes from that,
2957 but making sure we still get a positive number.
2958 The return value may also be a negative number; an error
2959 value. We cover this case by comparing against remaining,
2960 which is always >= 0. */
2961 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
2962 retval
= (int) bfd_getl_signed_32 (r10_buf
);
2963 if (retval
>= remaining
)
2964 bfd_putl32 (retval
- remaining
, r10_buf
);
2965 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
2967 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
2968 memcpy (cpu
->thread_data
[i
].cpu_context
,
2969 &cpu
->cpu_data_placeholder
,
2970 cpu
->thread_cpu_data_size
);
2971 memcpy (&cpu
->cpu_data_placeholder
,
2972 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
2973 cpu
->thread_cpu_data_size
);
2974 cpu
->thread_data
[i
].pipe_read_fd
= 0;
2975 cpu
->thread_data
[i
].pipe_write_fd
= 0;
2982 /* We have a simulator-specific notion of time. See TARGET_TIME. */
2985 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
2987 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
2993 /* Set target-specific callback data. */
2996 cris_set_callbacks (host_callback
*cb
)
2998 /* Yeargh, have to cast away constness to avoid warnings. */
2999 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3000 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3002 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3003 parameter to cb_store_target_endian will make st_size negative.
3004 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3005 *unsigned*, and/or add syntax for signed-ness. */
3006 cb
->stat_map
= stat_map
;
3007 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3008 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3009 cb
->pipe_empty
= cris_pipe_empty
;
3010 cb
->time
= cris_time
;
3013 /* Process an address exception. */
3016 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3017 unsigned int map
, int nr_bytes
, address_word addr
,
3018 transfer_type transfer
, sim_core_signals sig
)
3020 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,