OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [cris/] [traps.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* CRIS exception, interrupt, and trap (EIT) support
2
   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
4
   Contributed by Axis Communications.
5
 
6
This file is part of the GNU simulators.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "sim-main.h"
22
#include "sim-options.h"
23
#include "bfd.h"
24
/* FIXME: get rid of targ-vals.h usage everywhere else.  */
25
 
26
#include <stdarg.h>
27
#ifdef HAVE_ERRNO_H
28
#include <errno.h>
29
#endif
30
#ifdef HAVE_UNISTD_H
31
#include <unistd.h>
32
#endif
33
#ifdef HAVE_FCNTL_H
34
#include <fcntl.h>
35
#endif
36
#ifdef HAVE_SYS_PARAM_H
37
#include <sys/param.h>
38
#endif
39
#ifdef HAVE_SYS_STAT_H
40
#include <sys/stat.h>
41
#endif
42
/* For PATH_MAX, originally. */
43
#ifdef HAVE_LIMITS_H
44
#include <limits.h>
45
#endif
46
 
47
/* From ld/sysdep.h.  */
48
#ifdef PATH_MAX
49
# define SIM_PATHMAX PATH_MAX
50
#else
51
# ifdef MAXPATHLEN
52
#  define SIM_PATHMAX MAXPATHLEN
53
# else
54
#  define SIM_PATHMAX 1024
55
# endif
56
#endif
57
 
58
/* The verbatim values are from asm-cris/unistd.h.  */
59
 
60
#define TARGET_SYS_exit 1
61
#define TARGET_SYS_read 3
62
#define TARGET_SYS_write 4
63
#define TARGET_SYS_open 5
64
#define TARGET_SYS_close 6
65
#define TARGET_SYS_unlink 10
66
#define TARGET_SYS_time 13
67
#define TARGET_SYS_lseek 19
68
#define TARGET_SYS_getpid 20
69
#define TARGET_SYS_access 33
70
#define TARGET_SYS_kill 37
71
#define TARGET_SYS_rename 38
72
#define TARGET_SYS_pipe 42
73
#define TARGET_SYS_brk 45
74
#define TARGET_SYS_ioctl 54
75
#define TARGET_SYS_fcntl 55
76
#define TARGET_SYS_getppid 64
77
#define TARGET_SYS_setrlimit 75
78
#define TARGET_SYS_gettimeofday  78
79
#define TARGET_SYS_readlink 85
80
#define TARGET_SYS_munmap 91
81
#define TARGET_SYS_truncate 92
82
#define TARGET_SYS_ftruncate 93
83
#define TARGET_SYS_socketcall 102
84
#define TARGET_SYS_stat 106
85
#define TARGET_SYS_fstat 108
86
#define TARGET_SYS_wait4 114
87
#define TARGET_SYS_sigreturn 119
88
#define TARGET_SYS_clone 120
89
#define TARGET_SYS_uname 122
90
#define TARGET_SYS_mprotect 125
91
#define TARGET_SYS_llseek 140
92
#define TARGET_SYS_writev 146
93
#define TARGET_SYS__sysctl 149
94
#define TARGET_SYS_sched_setparam 154
95
#define TARGET_SYS_sched_getparam 155
96
#define TARGET_SYS_sched_setscheduler 156
97
#define TARGET_SYS_sched_getscheduler 157
98
#define TARGET_SYS_sched_yield 158
99
#define TARGET_SYS_sched_get_priority_max 159
100
#define TARGET_SYS_sched_get_priority_min 160
101
#define TARGET_SYS_mremap 163
102
#define TARGET_SYS_poll 168
103
#define TARGET_SYS_rt_sigaction 174
104
#define TARGET_SYS_rt_sigprocmask 175
105
#define TARGET_SYS_rt_sigsuspend 179
106
#define TARGET_SYS_getcwd 183
107
#define TARGET_SYS_ugetrlimit 191
108
#define TARGET_SYS_mmap2 192
109
#define TARGET_SYS_stat64 195
110
#define TARGET_SYS_lstat64 196
111
#define TARGET_SYS_fstat64 197
112
#define TARGET_SYS_geteuid32 201
113
#define TARGET_SYS_getuid32 199
114
#define TARGET_SYS_getegid32 202
115
#define TARGET_SYS_getgid32 200
116
#define TARGET_SYS_fcntl64 221
117
#define TARGET_SYS_set_thread_area 243
118
#define TARGET_SYS_exit_group 252
119
 
120
#define TARGET_PROT_READ        0x1
121
#define TARGET_PROT_WRITE       0x2
122
#define TARGET_PROT_EXEC        0x4
123
#define TARGET_PROT_NONE        0x0
124
 
125
#define TARGET_MAP_SHARED       0x01
126
#define TARGET_MAP_PRIVATE      0x02
127
#define TARGET_MAP_TYPE         0x0f
128
#define TARGET_MAP_FIXED        0x10
129
#define TARGET_MAP_ANONYMOUS    0x20
130
#define TARGET_MAP_DENYWRITE    0x800
131
 
132
#define TARGET_CTL_KERN         1
133
#define TARGET_CTL_VM           2
134
#define TARGET_CTL_NET          3
135
#define TARGET_CTL_PROC         4
136
#define TARGET_CTL_FS           5
137
#define TARGET_CTL_DEBUG        6
138
#define TARGET_CTL_DEV          7
139
#define TARGET_CTL_BUS          8
140
#define TARGET_CTL_ABI          9
141
 
142
#define TARGET_CTL_KERN_VERSION 4
143
 
144
/* linux/mman.h */
145
#define TARGET_MREMAP_MAYMOVE  1
146
#define TARGET_MREMAP_FIXED    2
147
 
148
#define TARGET_TCGETS 0x5401
149
 
150
#define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
151
 
152
/* Seconds since 1970-01-01 to the above date + 10 minutes;
153
   'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'.  */
154
#define TARGET_EPOCH 1230764410
155
 
156
/* Milliseconds since start of run.  We use the number of syscalls to
157
   avoid introducing noise in the execution time.  */
158
#define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
159
 
160
/* Seconds as in time(2).  */
161
#define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
162
 
163
#define TARGET_SCHED_OTHER 0
164
 
165
#define TARGET_RLIMIT_STACK 3
166
#define TARGET_RLIMIT_NOFILE 7
167
 
168
#define SIM_TARGET_MAX_THREADS 64
169
#define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
170
 
171
/* From linux/sched.h.  */
172
#define TARGET_CSIGNAL 0x000000ff
173
#define TARGET_CLONE_VM 0x00000100
174
#define TARGET_CLONE_FS 0x00000200
175
#define TARGET_CLONE_FILES 0x00000400
176
#define TARGET_CLONE_SIGHAND 0x00000800
177
#define TARGET_CLONE_PID 0x00001000
178
#define TARGET_CLONE_PTRACE 0x00002000
179
#define TARGET_CLONE_VFORK 0x00004000
180
#define TARGET_CLONE_PARENT 0x00008000
181
#define TARGET_CLONE_THREAD 0x00010000
182
#define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
183
 
184
/* From asm-cris/poll.h.  */
185
#define TARGET_POLLIN 1
186
 
187
/* From asm-cris/signal.h.  */
188
#define TARGET_SIG_BLOCK 0
189
#define TARGET_SIG_UNBLOCK 1
190
#define TARGET_SIG_SETMASK 2
191
 
192
#define TARGET_SIG_DFL 0
193
#define TARGET_SIG_IGN 1
194
#define TARGET_SIG_ERR ((USI)-1)
195
 
196
#define TARGET_SIGHUP 1
197
#define TARGET_SIGINT 2
198
#define TARGET_SIGQUIT 3
199
#define TARGET_SIGILL 4
200
#define TARGET_SIGTRAP 5
201
#define TARGET_SIGABRT 6
202
#define TARGET_SIGIOT 6
203
#define TARGET_SIGBUS 7
204
#define TARGET_SIGFPE 8
205
#define TARGET_SIGKILL 9
206
#define TARGET_SIGUSR1 10
207
#define TARGET_SIGSEGV 11
208
#define TARGET_SIGUSR2 12
209
#define TARGET_SIGPIPE 13
210
#define TARGET_SIGALRM 14
211
#define TARGET_SIGTERM 15
212
#define TARGET_SIGSTKFLT 16
213
#define TARGET_SIGCHLD 17
214
#define TARGET_SIGCONT 18
215
#define TARGET_SIGSTOP 19
216
#define TARGET_SIGTSTP 20
217
#define TARGET_SIGTTIN 21
218
#define TARGET_SIGTTOU 22
219
#define TARGET_SIGURG 23
220
#define TARGET_SIGXCPU 24
221
#define TARGET_SIGXFSZ 25
222
#define TARGET_SIGVTALRM 26
223
#define TARGET_SIGPROF 27
224
#define TARGET_SIGWINCH 28
225
#define TARGET_SIGIO 29
226
#define TARGET_SIGPOLL SIGIO
227
/* Actually commented out in the kernel header.  */
228
#define TARGET_SIGLOST 29
229
#define TARGET_SIGPWR 30
230
#define TARGET_SIGSYS 31
231
 
232
/* From include/asm-cris/signal.h.  */
233
#define TARGET_SA_NOCLDSTOP 0x00000001
234
#define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
235
#define TARGET_SA_SIGINFO 0x00000004
236
#define TARGET_SA_ONSTACK 0x08000000
237
#define TARGET_SA_RESTART 0x10000000
238
#define TARGET_SA_NODEFER 0x40000000
239
#define TARGET_SA_RESETHAND 0x80000000
240
#define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
241
#define TARGET_SA_RESTORER 0x04000000
242
 
243
/* From linux/wait.h.  */
244
#define TARGET_WNOHANG 1
245
#define TARGET_WUNTRACED 2
246
#define TARGET___WNOTHREAD 0x20000000
247
#define TARGET___WALL 0x40000000
248
#define TARGET___WCLONE 0x80000000
249
 
250
/* From linux/limits.h. */
251
#define TARGET_PIPE_BUF 4096
252
 
253
/* From unistd.h.  */
254
#define TARGET_R_OK 4
255
#define TARGET_W_OK 2
256
#define TARGET_X_OK 1
257
#define TARGET_F_OK 0
258
 
259
static const char stat_map[] =
260
"st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
261
":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
262
":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
263
":st_ino,8";
264
 
265
static const CB_TARGET_DEFS_MAP syscall_map[] =
266
{
267
  { CB_SYS_open, TARGET_SYS_open },
268
  { CB_SYS_close, TARGET_SYS_close },
269
  { CB_SYS_read, TARGET_SYS_read },
270
  { CB_SYS_write, TARGET_SYS_write },
271
  { CB_SYS_lseek, TARGET_SYS_lseek },
272
  { CB_SYS_unlink, TARGET_SYS_unlink },
273
  { CB_SYS_getpid, TARGET_SYS_getpid },
274
  { CB_SYS_fstat, TARGET_SYS_fstat64 },
275
  { CB_SYS_lstat, TARGET_SYS_lstat64 },
276
  { CB_SYS_stat, TARGET_SYS_stat64 },
277
  { CB_SYS_pipe, TARGET_SYS_pipe },
278
  { CB_SYS_rename, TARGET_SYS_rename },
279
  { CB_SYS_truncate, TARGET_SYS_truncate },
280
  { CB_SYS_ftruncate, TARGET_SYS_ftruncate },
281
  { 0, -1 }
282
};
283
 
284
/* An older, 32-bit-only stat mapping.  */
285
static const char stat32_map[] =
286
"st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
287
":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
288
":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
289
 
290
/* Map for calls using the 32-bit struct stat.  Primarily used by the
291
   newlib Linux mapping.  */
292
static const CB_TARGET_DEFS_MAP syscall_stat32_map[] =
293
{
294
  { CB_SYS_fstat, TARGET_SYS_fstat },
295
  { CB_SYS_stat, TARGET_SYS_stat },
296
  { 0, -1 }
297
};
298
 
299
/* Giving the true value for the running sim process will lead to
300
   non-time-invariant behavior.  */
301
#define TARGET_PID 42
302
 
303
/* Unfortunately, we don't get this from cris.cpu at the moment, and if
304
   we did, we'd still don't get a register number with the "16" offset.  */
305
#define TARGET_SRP_REGNUM (16+11)
306
 
307
/* Extracted by applying
308
   awk '/^#define/ { printf "#ifdef %s\n  { %s, %s },\n#endif\n", $2, $2, $3;}'
309
   on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
310
   adjusting the synonyms.  */
311
 
312
static const CB_TARGET_DEFS_MAP errno_map[] =
313
{
314
#ifdef EPERM
315
  { EPERM, 1 },
316
#endif
317
#ifdef ENOENT
318
  { ENOENT, 2 },
319
#endif
320
#ifdef ESRCH
321
  { ESRCH, 3 },
322
#endif
323
#ifdef EINTR
324
  { EINTR, 4 },
325
#endif
326
#ifdef EIO
327
  { EIO, 5 },
328
#endif
329
#ifdef ENXIO
330
  { ENXIO, 6 },
331
#endif
332
#ifdef E2BIG
333
  { E2BIG, 7 },
334
#endif
335
#ifdef ENOEXEC
336
  { ENOEXEC, 8 },
337
#endif
338
#ifdef EBADF
339
  { EBADF, 9 },
340
#endif
341
#ifdef ECHILD
342
  { ECHILD, 10 },
343
#endif
344
#ifdef EAGAIN
345
  { EAGAIN, 11 },
346
#endif
347
#ifdef ENOMEM
348
  { ENOMEM, 12 },
349
#endif
350
#ifdef EACCES
351
  { EACCES, 13 },
352
#endif
353
#ifdef EFAULT
354
  { EFAULT, 14 },
355
#endif
356
#ifdef ENOTBLK
357
  { ENOTBLK, 15 },
358
#endif
359
#ifdef EBUSY
360
  { EBUSY, 16 },
361
#endif
362
#ifdef EEXIST
363
  { EEXIST, 17 },
364
#endif
365
#ifdef EXDEV
366
  { EXDEV, 18 },
367
#endif
368
#ifdef ENODEV
369
  { ENODEV, 19 },
370
#endif
371
#ifdef ENOTDIR
372
  { ENOTDIR, 20 },
373
#endif
374
#ifdef EISDIR
375
  { EISDIR, 21 },
376
#endif
377
#ifdef EINVAL
378
  { EINVAL, 22 },
379
#endif
380
#ifdef ENFILE
381
  { ENFILE, 23 },
382
#endif
383
#ifdef EMFILE
384
  { EMFILE, 24 },
385
#endif
386
#ifdef ENOTTY
387
  { ENOTTY, 25 },
388
#endif
389
#ifdef ETXTBSY
390
  { ETXTBSY, 26 },
391
#endif
392
#ifdef EFBIG
393
  { EFBIG, 27 },
394
#endif
395
#ifdef ENOSPC
396
  { ENOSPC, 28 },
397
#endif
398
#ifdef ESPIPE
399
  { ESPIPE, 29 },
400
#endif
401
#ifdef EROFS
402
  { EROFS, 30 },
403
#endif
404
#ifdef EMLINK
405
  { EMLINK, 31 },
406
#endif
407
#ifdef EPIPE
408
  { EPIPE, 32 },
409
#endif
410
#ifdef EDOM
411
  { EDOM, 33 },
412
#endif
413
#ifdef ERANGE
414
  { ERANGE, 34 },
415
#endif
416
#ifdef EDEADLK
417
  { EDEADLK, 35 },
418
#endif
419
#ifdef ENAMETOOLONG
420
  { ENAMETOOLONG, 36 },
421
#endif
422
#ifdef ENOLCK
423
  { ENOLCK, 37 },
424
#endif
425
#ifdef ENOSYS
426
  { ENOSYS, 38 },
427
#endif
428
#ifdef ENOTEMPTY
429
  { ENOTEMPTY, 39 },
430
#endif
431
#ifdef ELOOP
432
  { ELOOP, 40 },
433
#endif
434
#ifdef EWOULDBLOCK
435
  { EWOULDBLOCK, 11 },
436
#endif
437
#ifdef ENOMSG
438
  { ENOMSG, 42 },
439
#endif
440
#ifdef EIDRM
441
  { EIDRM, 43 },
442
#endif
443
#ifdef ECHRNG
444
  { ECHRNG, 44 },
445
#endif
446
#ifdef EL2NSYNC
447
  { EL2NSYNC, 45 },
448
#endif
449
#ifdef EL3HLT
450
  { EL3HLT, 46 },
451
#endif
452
#ifdef EL3RST
453
  { EL3RST, 47 },
454
#endif
455
#ifdef ELNRNG
456
  { ELNRNG, 48 },
457
#endif
458
#ifdef EUNATCH
459
  { EUNATCH, 49 },
460
#endif
461
#ifdef ENOCSI
462
  { ENOCSI, 50 },
463
#endif
464
#ifdef EL2HLT
465
  { EL2HLT, 51 },
466
#endif
467
#ifdef EBADE
468
  { EBADE, 52 },
469
#endif
470
#ifdef EBADR
471
  { EBADR, 53 },
472
#endif
473
#ifdef EXFULL
474
  { EXFULL, 54 },
475
#endif
476
#ifdef ENOANO
477
  { ENOANO, 55 },
478
#endif
479
#ifdef EBADRQC
480
  { EBADRQC, 56 },
481
#endif
482
#ifdef EBADSLT
483
  { EBADSLT, 57 },
484
#endif
485
#ifdef EDEADLOCK
486
  { EDEADLOCK, 35 },
487
#endif
488
#ifdef EBFONT
489
  { EBFONT, 59 },
490
#endif
491
#ifdef ENOSTR
492
  { ENOSTR, 60 },
493
#endif
494
#ifdef ENODATA
495
  { ENODATA, 61 },
496
#endif
497
#ifdef ETIME
498
  { ETIME, 62 },
499
#endif
500
#ifdef ENOSR
501
  { ENOSR, 63 },
502
#endif
503
#ifdef ENONET
504
  { ENONET, 64 },
505
#endif
506
#ifdef ENOPKG
507
  { ENOPKG, 65 },
508
#endif
509
#ifdef EREMOTE
510
  { EREMOTE, 66 },
511
#endif
512
#ifdef ENOLINK
513
  { ENOLINK, 67 },
514
#endif
515
#ifdef EADV
516
  { EADV, 68 },
517
#endif
518
#ifdef ESRMNT
519
  { ESRMNT, 69 },
520
#endif
521
#ifdef ECOMM
522
  { ECOMM, 70 },
523
#endif
524
#ifdef EPROTO
525
  { EPROTO, 71 },
526
#endif
527
#ifdef EMULTIHOP
528
  { EMULTIHOP, 72 },
529
#endif
530
#ifdef EDOTDOT
531
  { EDOTDOT, 73 },
532
#endif
533
#ifdef EBADMSG
534
  { EBADMSG, 74 },
535
#endif
536
#ifdef EOVERFLOW
537
  { EOVERFLOW, 75 },
538
#endif
539
#ifdef ENOTUNIQ
540
  { ENOTUNIQ, 76 },
541
#endif
542
#ifdef EBADFD
543
  { EBADFD, 77 },
544
#endif
545
#ifdef EREMCHG
546
  { EREMCHG, 78 },
547
#endif
548
#ifdef ELIBACC
549
  { ELIBACC, 79 },
550
#endif
551
#ifdef ELIBBAD
552
  { ELIBBAD, 80 },
553
#endif
554
#ifdef ELIBSCN
555
  { ELIBSCN, 81 },
556
#endif
557
#ifdef ELIBMAX
558
  { ELIBMAX, 82 },
559
#endif
560
#ifdef ELIBEXEC
561
  { ELIBEXEC, 83 },
562
#endif
563
#ifdef EILSEQ
564
  { EILSEQ, 84 },
565
#endif
566
#ifdef ERESTART
567
  { ERESTART, 85 },
568
#endif
569
#ifdef ESTRPIPE
570
  { ESTRPIPE, 86 },
571
#endif
572
#ifdef EUSERS
573
  { EUSERS, 87 },
574
#endif
575
#ifdef ENOTSOCK
576
  { ENOTSOCK, 88 },
577
#endif
578
#ifdef EDESTADDRREQ
579
  { EDESTADDRREQ, 89 },
580
#endif
581
#ifdef EMSGSIZE
582
  { EMSGSIZE, 90 },
583
#endif
584
#ifdef EPROTOTYPE
585
  { EPROTOTYPE, 91 },
586
#endif
587
#ifdef ENOPROTOOPT
588
  { ENOPROTOOPT, 92 },
589
#endif
590
#ifdef EPROTONOSUPPORT
591
  { EPROTONOSUPPORT, 93 },
592
#endif
593
#ifdef ESOCKTNOSUPPORT
594
  { ESOCKTNOSUPPORT, 94 },
595
#endif
596
#ifdef EOPNOTSUPP
597
  { EOPNOTSUPP, 95 },
598
#endif
599
#ifdef EPFNOSUPPORT
600
  { EPFNOSUPPORT, 96 },
601
#endif
602
#ifdef EAFNOSUPPORT
603
  { EAFNOSUPPORT, 97 },
604
#endif
605
#ifdef EADDRINUSE
606
  { EADDRINUSE, 98 },
607
#endif
608
#ifdef EADDRNOTAVAIL
609
  { EADDRNOTAVAIL, 99 },
610
#endif
611
#ifdef ENETDOWN
612
  { ENETDOWN, 100 },
613
#endif
614
#ifdef ENETUNREACH
615
  { ENETUNREACH, 101 },
616
#endif
617
#ifdef ENETRESET
618
  { ENETRESET, 102 },
619
#endif
620
#ifdef ECONNABORTED
621
  { ECONNABORTED, 103 },
622
#endif
623
#ifdef ECONNRESET
624
  { ECONNRESET, 104 },
625
#endif
626
#ifdef ENOBUFS
627
  { ENOBUFS, 105 },
628
#endif
629
#ifdef EISCONN
630
  { EISCONN, 106 },
631
#endif
632
#ifdef ENOTCONN
633
  { ENOTCONN, 107 },
634
#endif
635
#ifdef ESHUTDOWN
636
  { ESHUTDOWN, 108 },
637
#endif
638
#ifdef ETOOMANYREFS
639
  { ETOOMANYREFS, 109 },
640
#endif
641
#ifdef ETIMEDOUT
642
  { ETIMEDOUT, 110 },
643
#endif
644
#ifdef ECONNREFUSED
645
  { ECONNREFUSED, 111 },
646
#endif
647
#ifdef EHOSTDOWN
648
  { EHOSTDOWN, 112 },
649
#endif
650
#ifdef EHOSTUNREACH
651
  { EHOSTUNREACH, 113 },
652
#endif
653
#ifdef EALREADY
654
  { EALREADY, 114 },
655
#endif
656
#ifdef EINPROGRESS
657
  { EINPROGRESS, 115 },
658
#endif
659
#ifdef ESTALE
660
  { ESTALE, 116 },
661
#endif
662
#ifdef EUCLEAN
663
  { EUCLEAN, 117 },
664
#endif
665
#ifdef ENOTNAM
666
  { ENOTNAM, 118 },
667
#endif
668
#ifdef ENAVAIL
669
  { ENAVAIL, 119 },
670
#endif
671
#ifdef EISNAM
672
  { EISNAM, 120 },
673
#endif
674
#ifdef EREMOTEIO
675
  { EREMOTEIO, 121 },
676
#endif
677
#ifdef EDQUOT
678
  { EDQUOT, 122 },
679
#endif
680
#ifdef ENOMEDIUM
681
  { ENOMEDIUM, 123 },
682
#endif
683
#ifdef EMEDIUMTYPE
684
  { EMEDIUMTYPE, 124 },
685
#endif
686
  { 0, -1 }
687
};
688
 
689
/* Extracted by applying
690
   perl -ne 'if ($_ =~ /^#define/) { split;
691
     printf "#ifdef $_[1]\n  { %s, 0x%x },\n#endif\n",
692
             $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
693
   on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
694
   installation and removing synonyms and unnecessary items.  Don't
695
   forget the end-marker.  */
696
 
697
/* These we treat specially, as they're used in the fcntl F_GETFL
698
   syscall.  For consistency, open_map is also manually edited to use
699
   these macros.  */
700
#define TARGET_O_ACCMODE 0x3
701
#define TARGET_O_RDONLY 0x0
702
#define TARGET_O_WRONLY 0x1
703
 
704
static const CB_TARGET_DEFS_MAP open_map[] = {
705
#ifdef O_ACCMODE
706
  { O_ACCMODE, TARGET_O_ACCMODE },
707
#endif
708
#ifdef O_RDONLY
709
  { O_RDONLY, TARGET_O_RDONLY },
710
#endif
711
#ifdef O_WRONLY
712
  { O_WRONLY, TARGET_O_WRONLY },
713
#endif
714
#ifdef O_RDWR
715
  { O_RDWR, 0x2 },
716
#endif
717
#ifdef O_CREAT
718
  { O_CREAT, 0x40 },
719
#endif
720
#ifdef O_EXCL
721
  { O_EXCL, 0x80 },
722
#endif
723
#ifdef O_NOCTTY
724
  { O_NOCTTY, 0x100 },
725
#endif
726
#ifdef O_TRUNC
727
  { O_TRUNC, 0x200 },
728
#endif
729
#ifdef O_APPEND
730
  { O_APPEND, 0x400 },
731
#endif
732
#ifdef O_NONBLOCK
733
  { O_NONBLOCK, 0x800 },
734
#endif
735
#ifdef O_NDELAY
736
  { O_NDELAY, 0x0 },
737
#endif
738
#ifdef O_SYNC
739
  { O_SYNC, 0x1000 },
740
#endif
741
#ifdef FASYNC
742
  { FASYNC, 0x2000 },
743
#endif
744
#ifdef O_DIRECT
745
  { O_DIRECT, 0x4000 },
746
#endif
747
#ifdef O_LARGEFILE
748
  { O_LARGEFILE, 0x8000 },
749
#endif
750
#ifdef O_DIRECTORY
751
  { O_DIRECTORY, 0x10000 },
752
#endif
753
#ifdef O_NOFOLLOW
754
  { O_NOFOLLOW, 0x20000 },
755
#endif
756
  { -1, -1 }
757
};
758
 
759
/* Let's be less drastic and more traceable.  FIXME: mark as noreturn.  */
760
#define abort()                                                 \
761
  sim_io_error (sd, "simulator unhandled condition at %s:%d",   \
762
                __FUNCTION__, __LINE__)
763
 
764
/* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls.  */
765
static SIM_CPU *current_cpu_for_cb_callback;
766
 
767
static int syscall_read_mem (host_callback *, struct cb_syscall *,
768
                             unsigned long, char *, int);
769
static int syscall_write_mem (host_callback *, struct cb_syscall *,
770
                              unsigned long, const char *, int);
771
static USI create_map (SIM_DESC, struct cris_sim_mmapped_page **,
772
                       USI addr, USI len);
773
static USI unmap_pages (SIM_DESC, struct cris_sim_mmapped_page **,
774
                       USI addr, USI len);
775
static USI is_mapped (SIM_DESC, struct cris_sim_mmapped_page **,
776
                       USI addr, USI len);
777
static void dump_statistics (SIM_CPU *current_cpu);
778
static void make_first_thread (SIM_CPU *current_cpu);
779
 
780
/* Read/write functions for system call interface.  */
781
 
782
static int
783
syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED,
784
                  struct cb_syscall *sc,
785
                  unsigned long taddr, char *buf, int bytes)
786
{
787
  SIM_DESC sd = (SIM_DESC) sc->p1;
788
  SIM_CPU *cpu = (SIM_CPU *) sc->p2;
789
 
790
  return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
791
}
792
 
793
static int
794
syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED,
795
                   struct cb_syscall *sc,
796
                   unsigned long taddr, const char *buf, int bytes)
797
{
798
  SIM_DESC sd = (SIM_DESC) sc->p1;
799
  SIM_CPU *cpu = (SIM_CPU *) sc->p2;
800
 
801
  return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
802
}
803
 
804
/* When we risk running self-modified code (as in trampolines), this is
805
   called from special-case insns.  The silicon CRIS CPU:s have enough
806
   cache snooping implemented making this a simulator-only issue.  Tests:
807
   gcc.c-torture/execute/931002-1.c execution, -O3 -g
808
   gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer.  */
809
 
810
void
811
cris_flush_simulator_decode_cache (SIM_CPU *current_cpu,
812
                                   USI pc ATTRIBUTE_UNUSED)
813
{
814
  SIM_DESC sd = CPU_STATE (current_cpu);
815
 
816
#if WITH_SCACHE
817
  if (USING_SCACHE_P (sd))
818
    scache_flush_cpu (current_cpu);
819
#endif
820
}
821
 
822
/* Output statistics at the end of a run.  */
823
static void
824
dump_statistics (SIM_CPU *current_cpu)
825
{
826
  SIM_DESC sd = CPU_STATE (current_cpu);
827
  CRIS_MISC_PROFILE *profp
828
    = CPU_CRIS_MISC_PROFILE (current_cpu);
829
  unsigned64 total = profp->basic_cycle_count;
830
  const char *textmsg = "Basic clock cycles, total @: %llu\n";
831
 
832
  /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
833
     what's included in the "total" count only.  */
834
  switch (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
835
          & FLAG_CRIS_MISC_PROFILE_ALL)
836
    {
837
    case FLAG_CRIS_MISC_PROFILE_SIMPLE:
838
      break;
839
 
840
    case (FLAG_CRIS_MISC_PROFILE_UNALIGNED | FLAG_CRIS_MISC_PROFILE_SIMPLE):
841
      textmsg
842
        = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
843
      total += profp->unaligned_mem_dword_count;
844
      break;
845
 
846
    case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE | FLAG_CRIS_MISC_PROFILE_SIMPLE):
847
      textmsg = "Schedulable clock cycles, total @: %llu\n";
848
      total
849
        += (profp->memsrc_stall_count
850
            + profp->memraw_stall_count
851
            + profp->movemsrc_stall_count
852
            + profp->movemdst_stall_count
853
            + profp->mulsrc_stall_count
854
            + profp->jumpsrc_stall_count
855
            + profp->unaligned_mem_dword_count);
856
      break;
857
 
858
    case FLAG_CRIS_MISC_PROFILE_ALL:
859
      textmsg = "All accounted clock cycles, total @: %llu\n";
860
      total
861
        += (profp->memsrc_stall_count
862
            + profp->memraw_stall_count
863
            + profp->movemsrc_stall_count
864
            + profp->movemdst_stall_count
865
            + profp->movemaddr_stall_count
866
            + profp->mulsrc_stall_count
867
            + profp->jumpsrc_stall_count
868
            + profp->branch_stall_count
869
            + profp->jumptarget_stall_count
870
            + profp->unaligned_mem_dword_count);
871
      break;
872
 
873
    default:
874
      abort ();
875
 
876
      sim_io_eprintf (sd,
877
                      "Internal inconsistency at %s:%d",
878
                      __FILE__, __LINE__);
879
      sim_engine_halt (sd, current_cpu, NULL, 0,
880
                       sim_stopped, SIM_SIGILL);
881
    }
882
 
883
  /* Historically, these messages have gone to stderr, so we'll keep it
884
     that way.  It's also easier to then tell it from normal program
885
     output.  FIXME: Add redirect option like "run -e file".  */
886
  sim_io_eprintf (sd, textmsg, total);
887
 
888
  /* For v32, unaligned_mem_dword_count should always be 0.  For
889
     v10, memsrc_stall_count should always be 0.  */
890
  sim_io_eprintf (sd, "Memory source stall cycles: %llu\n",
891
                  (unsigned long long) (profp->memsrc_stall_count
892
                                        + profp->unaligned_mem_dword_count));
893
  sim_io_eprintf (sd, "Memory read-after-write stall cycles: %llu\n",
894
                  (unsigned long long) profp->memraw_stall_count);
895
  sim_io_eprintf (sd, "Movem source stall cycles: %llu\n",
896
                  (unsigned long long) profp->movemsrc_stall_count);
897
  sim_io_eprintf (sd, "Movem destination stall cycles: %llu\n",
898
                  (unsigned long long) profp->movemdst_stall_count);
899
  sim_io_eprintf (sd, "Movem address stall cycles: %llu\n",
900
                  (unsigned long long) profp->movemaddr_stall_count);
901
  sim_io_eprintf (sd, "Multiplication source stall cycles: %llu\n",
902
                  (unsigned long long) profp->mulsrc_stall_count);
903
  sim_io_eprintf (sd, "Jump source stall cycles: %llu\n",
904
                  (unsigned long long) profp->jumpsrc_stall_count);
905
  sim_io_eprintf (sd, "Branch misprediction stall cycles: %llu\n",
906
                  (unsigned long long) profp->branch_stall_count);
907
  sim_io_eprintf (sd, "Jump target stall cycles: %llu\n",
908
                  (unsigned long long) profp->jumptarget_stall_count);
909
}
910
 
911
/* Check whether any part of [addr .. addr + len - 1] is already mapped.
912
   Return 1 if a overlap detected, 0 otherwise.  */
913
 
914
static USI
915
is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED,
916
           struct cris_sim_mmapped_page **rootp,
917
           USI addr, USI len)
918
{
919
  struct cris_sim_mmapped_page *mapp;
920
 
921
  if (len == 0 || (len & 8191))
922
    abort ();
923
 
924
  /* Iterate over the reverse-address sorted pages until we find a page in
925
     or lower than the checked area.  */
926
  for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
927
    if (mapp->addr < addr + len && mapp->addr >= addr)
928
      return 1;
929
 
930
  return 0;
931
}
932
 
933
/* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
934
   Return 1 if the whole area is mapped, 0 otherwise.  */
935
 
936
static USI
937
is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED,
938
                struct cris_sim_mmapped_page **rootp,
939
                USI addr, USI len)
940
{
941
  struct cris_sim_mmapped_page *mapp;
942
 
943
  if (len == 0 || (len & 8191))
944
    abort ();
945
 
946
  /* Iterate over the reverse-address sorted pages until we find a page
947
     lower than the checked area.  */
948
  for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
949
    if (addr == mapp->addr && len == 8192)
950
      return 1;
951
    else if (addr + len > mapp->addr)
952
      len -= 8192;
953
 
954
  return 0;
955
}
956
 
957
/* Debug helper; to be run from gdb.  */
958
 
959
void
960
cris_dump_map (SIM_CPU *current_cpu)
961
{
962
  struct cris_sim_mmapped_page *mapp;
963
  USI start, end;
964
 
965
  for (mapp = current_cpu->highest_mmapped_page,
966
         start = mapp == NULL ? 0 : mapp->addr + 8192,
967
         end = mapp == NULL ? 0 : mapp->addr + 8191;
968
       mapp != NULL;
969
       mapp = mapp->prev)
970
    {
971
      if (mapp->addr != start - 8192)
972
        {
973
          sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
974
          end = mapp->addr + 8191;
975
        }
976
 
977
      start = mapp->addr;
978
    }
979
 
980
  if (current_cpu->highest_mmapped_page != NULL)
981
    sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
982
}
983
 
984
/* Create mmapped memory.  ADDR is -1 if any address will do.  Caller
985
   must make sure that the address isn't already mapped.  */
986
 
987
static USI
988
create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
989
            USI len)
990
{
991
  struct cris_sim_mmapped_page *mapp;
992
  struct cris_sim_mmapped_page **higher_prevp = rootp;
993
  USI new_addr = 0x40000000;
994
 
995
  if (addr != (USI) -1)
996
    new_addr = addr;
997
  else if (*rootp && rootp[0]->addr >= new_addr)
998
    new_addr = rootp[0]->addr + 8192;
999
 
1000
  if (len != 8192)
1001
    {
1002
      USI page_addr;
1003
 
1004
      if (len & 8191)
1005
        /* Which is better: return an error for this, or just round it up?  */
1006
        abort ();
1007
 
1008
      /* Do a recursive call for each page in the request.  */
1009
      for (page_addr = new_addr; len != 0; page_addr += 8192, len -= 8192)
1010
        if (create_map (sd, rootp, page_addr, 8192) >= (USI) -8191)
1011
          abort ();
1012
 
1013
      return new_addr;
1014
    }
1015
 
1016
  for (mapp = *rootp;
1017
       mapp != NULL && mapp->addr > new_addr;
1018
       mapp = mapp->prev)
1019
    higher_prevp = &mapp->prev;
1020
 
1021
  /* Assert for consistency that we don't create duplicate maps.  */
1022
  if (is_mapped (sd, rootp, new_addr, len))
1023
    abort ();
1024
 
1025
  /* Allocate the new page, on the next higher page from the last one
1026
     allocated, and link in the new descriptor before previous ones.  */
1027
  mapp = malloc (sizeof (*mapp));
1028
 
1029
  if (mapp == NULL)
1030
    return (USI) -ENOMEM;
1031
 
1032
  sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1033
                   new_addr, len,
1034
                   0, NULL, NULL);
1035
 
1036
  mapp->addr = new_addr;
1037
  mapp->prev = *higher_prevp;
1038
  *higher_prevp = mapp;
1039
 
1040
  return new_addr;
1041
}
1042
 
1043
/* Unmap one or more pages.  */
1044
 
1045
static USI
1046
unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
1047
            USI len)
1048
{
1049
  struct cris_sim_mmapped_page *mapp;
1050
  struct cris_sim_mmapped_page **higher_prevp = rootp;
1051
 
1052
  if (len != 8192)
1053
    {
1054
      USI page_addr;
1055
      int ret = 0;
1056
 
1057
      if (len & 8191)
1058
        /* Which is better: return an error for this, or just round it up?  */
1059
        abort ();
1060
 
1061
      /* Loop backwards to make each call is O(1) over the number of pages
1062
         allocated, if we're unmapping from the high end of the pages.  */
1063
      for (page_addr = addr + len - 8192;
1064
           page_addr > addr;
1065
           page_addr -= 8192)
1066
        if (unmap_pages (sd, rootp, page_addr, 8192))
1067
          ret = EINVAL;
1068
 
1069
      if (unmap_pages (sd, rootp, addr, 8192))
1070
        ret = EINVAL;
1071
 
1072
      return ret;
1073
    }
1074
 
1075
  for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev)
1076
    higher_prevp = &mapp->prev;
1077
 
1078
  if (mapp == NULL || mapp->addr != addr)
1079
    return EINVAL;
1080
 
1081
  *higher_prevp = mapp->prev;
1082
  sim_core_detach (sd, NULL, 0, 0, addr);
1083
  free (mapp);
1084
  return 0;
1085
}
1086
 
1087
/* The semantic code invokes this for illegal (unrecognized) instructions.  */
1088
 
1089
SEM_PC
1090
sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
1091
{
1092
  SIM_DESC sd = CPU_STATE (current_cpu);
1093
 
1094
  sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
1095
  return vpc;
1096
}
1097
 
1098
/* Handlers from the CGEN description that should not be called.  */
1099
 
1100
USI
1101
cris_bmod_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1102
                   UINT srcreg ATTRIBUTE_UNUSED,
1103
                   USI dstreg ATTRIBUTE_UNUSED)
1104
{
1105
  SIM_DESC sd = CPU_STATE (current_cpu);
1106
  abort ();
1107
}
1108
 
1109
void
1110
h_supr_set_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1111
                    UINT index ATTRIBUTE_UNUSED,
1112
                    USI page ATTRIBUTE_UNUSED,
1113
                    USI newval ATTRIBUTE_UNUSED)
1114
{
1115
  SIM_DESC sd = CPU_STATE (current_cpu);
1116
  abort ();
1117
}
1118
 
1119
USI
1120
h_supr_get_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1121
                    UINT index ATTRIBUTE_UNUSED,
1122
                    USI page ATTRIBUTE_UNUSED)
1123
{
1124
  SIM_DESC sd = CPU_STATE (current_cpu);
1125
  abort ();
1126
}
1127
 
1128
/* Swap one context for another.  */
1129
 
1130
static void
1131
schedule (SIM_CPU *current_cpu, int next)
1132
{
1133
  /* Need to mark context-switches in the trace output.  */
1134
  if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1135
       & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE))
1136
    cris_trace_printf (CPU_STATE (current_cpu), current_cpu,
1137
                       "\t#:%d\n", next);
1138
 
1139
  /* Copy the current context (if there is one) to its slot.  */
1140
  if (current_cpu->thread_data[current_cpu->threadno].cpu_context)
1141
    memcpy (current_cpu->thread_data[current_cpu->threadno].cpu_context,
1142
            &current_cpu->cpu_data_placeholder,
1143
            current_cpu->thread_cpu_data_size);
1144
 
1145
  /* Copy the new context from its slot.  */
1146
  memcpy (&current_cpu->cpu_data_placeholder,
1147
          current_cpu->thread_data[next].cpu_context,
1148
          current_cpu->thread_cpu_data_size);
1149
 
1150
  /* Update needed stuff to indicate the new context.  */
1151
  current_cpu->threadno = next;
1152
 
1153
  /* Handle pending signals.  */
1154
  if (current_cpu->thread_data[next].sigpending
1155
      /* We don't run nested signal handlers.  This means that pause(2)
1156
         and sigsuspend(2) do not work in sighandlers, but that
1157
         shouldn't be too hard a restriction.  It also greatly
1158
         simplifies the code.  */
1159
      && current_cpu->thread_data[next].cpu_context_atsignal == NULL)
1160
  {
1161
    int sig;
1162
 
1163
    /* See if there's really a pending, non-blocked handler.  We don't
1164
       queue signals, so just use the first one in ascending order.  */
1165
    for (sig = 0; sig < 64; sig++)
1166
      if (current_cpu->thread_data[next].sigdata[sig].pending
1167
          && !current_cpu->thread_data[next].sigdata[sig].blocked)
1168
      {
1169
        bfd_byte regbuf[4];
1170
        USI sp;
1171
        int i;
1172
        USI blocked;
1173
        USI pc = sim_pc_get (current_cpu);
1174
 
1175
        /* It's simpler to save the CPU context inside the simulator
1176
           than on the stack.  */
1177
        current_cpu->thread_data[next].cpu_context_atsignal
1178
          = (*current_cpu
1179
             ->make_thread_cpu_data) (current_cpu,
1180
                                      current_cpu->thread_data[next]
1181
                                      .cpu_context);
1182
 
1183
        (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1184
        sp = bfd_getl32 (regbuf);
1185
 
1186
        /* Make sure we have an aligned stack.  */
1187
        sp &= ~3;
1188
 
1189
        /* Make room for the signal frame, aligned.  FIXME: Check that
1190
           the memory exists, map it in if absent.  (BTW, should also
1191
           implement on-access automatic stack allocation).  */
1192
        sp -= 20;
1193
 
1194
        /* This isn't the same signal frame as the kernel uses, because
1195
           we don't want to bother getting all registers on and off the
1196
           stack.  */
1197
 
1198
        /* First, we store the currently blocked signals.  */
1199
        blocked = 0;
1200
        for (i = 0; i < 32; i++)
1201
          blocked
1202
            |= current_cpu->thread_data[next].sigdata[i + 1].blocked << i;
1203
        sim_core_write_aligned_4 (current_cpu, pc, 0, sp, blocked);
1204
        blocked = 0;
1205
        for (i = 0; i < 31; i++)
1206
          blocked
1207
            |= current_cpu->thread_data[next].sigdata[i + 33].blocked << i;
1208
        sim_core_write_aligned_4 (current_cpu, pc, 0, sp + 4, blocked);
1209
 
1210
        /* Then, the actual instructions.  This is CPU-specific, but we
1211
           use instructions from the common subset for v10 and v32 which
1212
           should be safe for the time being but could be parametrized
1213
           if need be.  */
1214
        /* MOVU.W [PC+],R9.  */
1215
        sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 8, 0x9c5f);
1216
        /* .WORD TARGET_SYS_sigreturn.  */
1217
        sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 10,
1218
                                  TARGET_SYS_sigreturn);
1219
        /* BREAK 13.  */
1220
        sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 12, 0xe93d);
1221
 
1222
        /* NOP (on v32; it's SETF on v10, but is the correct compatible
1223
           instruction.  Still, it doesn't matter because v10 has no
1224
           delay slot for BREAK so it will not be executed).  */
1225
        sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 16, 0x05b0);
1226
 
1227
        /* Modify registers to hold the right values for the sighandler
1228
           context: updated stackpointer and return address pointing to
1229
           the sigreturn stub.  */
1230
        bfd_putl32 (sp, regbuf);
1231
        (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1232
        bfd_putl32 (sp + 8, regbuf);
1233
        (*CPU_REG_STORE (current_cpu)) (current_cpu, TARGET_SRP_REGNUM,
1234
                                        regbuf, 4);
1235
 
1236
        current_cpu->thread_data[next].sigdata[sig].pending = 0;
1237
 
1238
        /* Block this signal (for the duration of the sighandler).  */
1239
        current_cpu->thread_data[next].sigdata[sig].blocked = 1;
1240
 
1241
        sim_pc_set (current_cpu, current_cpu->sighandler[sig]);
1242
        bfd_putl32 (sig, regbuf);
1243
        (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10,
1244
                                        regbuf, 4);
1245
 
1246
        /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1247
           needed all this for, specifies a SA_SIGINFO call but treats it
1248
           like an ordinary sighandler; only the signal number argument is
1249
           inspected.  To make future need to implement SA_SIGINFO
1250
           correctly possible, we set the siginfo argument register to a
1251
           magic (hopefully non-address) number.  (NB: then, you should
1252
           just need to pass the siginfo argument; it seems you probably
1253
           don't need to implement the specific rt_sigreturn.)  */
1254
        bfd_putl32 (0xbad5161f, regbuf);
1255
        (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R11,
1256
                                        regbuf, 4);
1257
 
1258
        /* The third argument is unused and the kernel sets it to 0.  */
1259
        bfd_putl32 (0, regbuf);
1260
        (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R12,
1261
                                        regbuf, 4);
1262
        return;
1263
      }
1264
 
1265
    /* No, there actually was no pending signal for this thread.  Reset
1266
       this flag.  */
1267
    current_cpu->thread_data[next].sigpending = 0;
1268
  }
1269
}
1270
 
1271
/* Reschedule the simplest possible way until something else is absolutely
1272
   necessary:
1273
   - A. Find the next process (round-robin) that doesn't have at_syscall
1274
        set, schedule it.
1275
   - B. If there is none, just run the next process, round-robin.
1276
   - Clear at_syscall for the current process.  */
1277
 
1278
static void
1279
reschedule (SIM_CPU *current_cpu)
1280
{
1281
  SIM_DESC sd = CPU_STATE (current_cpu);
1282
  int i;
1283
 
1284
  /* Iterate over all thread slots, because after a few thread creations
1285
     and exits, we don't know where the live ones are.  */
1286
  for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1287
       i != current_cpu->threadno;
1288
       i = (i + 1) % SIM_TARGET_MAX_THREADS)
1289
    if (current_cpu->thread_data[i].cpu_context
1290
        && current_cpu->thread_data[i].at_syscall == 0)
1291
      {
1292
        schedule (current_cpu, i);
1293
        return;
1294
      }
1295
 
1296
  /* Pick any next live thread.  */
1297
  for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1298
       i != current_cpu->threadno;
1299
       i = (i + 1) % SIM_TARGET_MAX_THREADS)
1300
    if (current_cpu->thread_data[i].cpu_context)
1301
      {
1302
        schedule (current_cpu, i);
1303
        return;
1304
      }
1305
 
1306
  /* More than one live thread, but we couldn't find the next one?  */
1307
  abort ();
1308
}
1309
 
1310
/* Set up everything to receive (or IGN) an incoming signal to the
1311
   current context.  */
1312
 
1313
static int
1314
deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid)
1315
{
1316
  int i;
1317
  USI pc = sim_pc_get (current_cpu);
1318
 
1319
  /* Find the thread index of the pid. */
1320
  for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
1321
    /* Apparently it's ok to send signals to zombies (so a check for
1322
       current_cpu->thread_data[i].cpu_context != NULL would be
1323
       wrong). */
1324
    if (current_cpu->thread_data[i].threadid == pid - TARGET_PID)
1325
      {
1326
        if (sig < 64)
1327
          switch (current_cpu->sighandler[sig])
1328
            {
1329
            case TARGET_SIG_DFL:
1330
              switch (sig)
1331
                {
1332
                  /* The following according to the glibc
1333
                     documentation. (The kernel code has non-obvious
1334
                     execution paths.)  */
1335
                case TARGET_SIGFPE:
1336
                case TARGET_SIGILL:
1337
                case TARGET_SIGSEGV:
1338
                case TARGET_SIGBUS:
1339
                case TARGET_SIGABRT:
1340
                case TARGET_SIGTRAP:
1341
                case TARGET_SIGSYS:
1342
 
1343
                case TARGET_SIGTERM:
1344
                case TARGET_SIGINT:
1345
                case TARGET_SIGQUIT:
1346
                case TARGET_SIGKILL:
1347
                case TARGET_SIGHUP:
1348
 
1349
                case TARGET_SIGALRM:
1350
                case TARGET_SIGVTALRM:
1351
                case TARGET_SIGPROF:
1352
                case TARGET_SIGSTOP:
1353
 
1354
                case TARGET_SIGPIPE:
1355
                case TARGET_SIGLOST:
1356
                case TARGET_SIGXCPU:
1357
                case TARGET_SIGXFSZ:
1358
                case TARGET_SIGUSR1:
1359
                case TARGET_SIGUSR2:
1360
                  sim_io_eprintf (CPU_STATE (current_cpu),
1361
                                  "Exiting pid %d due to signal %d\n",
1362
                                  pid, sig);
1363
                  sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1364
                                   NULL, pc, sim_stopped,
1365
                                   sig == TARGET_SIGABRT
1366
                                   ? SIM_SIGABRT : SIM_SIGILL);
1367
                  return 0;
1368
 
1369
                  /* The default for all other signals is to be ignored.  */
1370
                default:
1371
                  return 0;
1372
                }
1373
 
1374
            case TARGET_SIG_IGN:
1375
              switch (sig)
1376
                {
1377
                case TARGET_SIGKILL:
1378
                case TARGET_SIGSTOP:
1379
                  /* Can't ignore these signals.  */
1380
                  sim_io_eprintf (CPU_STATE (current_cpu),
1381
                                  "Exiting pid %d due to signal %d\n",
1382
                                  pid, sig);
1383
                  sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1384
                                   NULL, pc, sim_stopped, SIM_SIGILL);
1385
                  return 0;
1386
 
1387
                default:
1388
                  return 0;
1389
                }
1390
              break;
1391
 
1392
            default:
1393
              /* Mark the signal as pending, making schedule () check
1394
                 closer.  The signal will be handled when the thread is
1395
                 scheduled and the signal is unblocked.  */
1396
              current_cpu->thread_data[i].sigdata[sig].pending = 1;
1397
              current_cpu->thread_data[i].sigpending = 1;
1398
              return 0;
1399
            }
1400
        else
1401
          {
1402
            sim_io_eprintf (CPU_STATE (current_cpu),
1403
                            "Unimplemented signal: %d\n", sig);
1404
            sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc,
1405
                             sim_stopped, SIM_SIGILL);
1406
          }
1407
      }
1408
 
1409
  return
1410
    -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu)),
1411
                              ESRCH);
1412
}
1413
 
1414
/* Make the vector and the first item, the main thread.  */
1415
 
1416
static void
1417
make_first_thread (SIM_CPU *current_cpu)
1418
{
1419
  SIM_DESC sd = CPU_STATE (current_cpu);
1420
  current_cpu->thread_data
1421
    = xcalloc (1,
1422
               SIM_TARGET_MAX_THREADS
1423
               * sizeof (current_cpu->thread_data[0]));
1424
  current_cpu->thread_data[0].cpu_context
1425
    = (*current_cpu->make_thread_cpu_data) (current_cpu,
1426
                                            &current_cpu
1427
                                            ->cpu_data_placeholder);
1428
  current_cpu->thread_data[0].parent_threadid = -1;
1429
 
1430
  /* For good measure.  */
1431
  if (TARGET_SIG_DFL != 0)
1432
    abort ();
1433
}
1434
 
1435
/* Handle unknown system calls.  Returns (if it does) the syscall
1436
   return value.  */
1437
 
1438
static USI
1439
cris_unknown_syscall (SIM_CPU *current_cpu, USI pc, char *s, ...)
1440
{
1441
  SIM_DESC sd = CPU_STATE (current_cpu);
1442
  host_callback *cb = STATE_CALLBACK (sd);
1443
 
1444
  if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP
1445
      || cris_unknown_syscall_action == CRIS_USYSC_MSG_ENOSYS)
1446
    {
1447
      va_list ap;
1448
 
1449
      va_start (ap, s);
1450
      sim_io_evprintf (sd, s, ap);
1451
      va_end (ap);
1452
 
1453
      if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP)
1454
        sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1455
    }
1456
 
1457
  return -cb_host_to_target_errno (cb, ENOSYS);
1458
}
1459
 
1460
/* Main function: the handler of the "break 13" syscall insn.  */
1461
 
1462
USI
1463
cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
1464
                       USI arg2, USI arg3, USI arg4, USI arg5, USI arg6,
1465
                       USI pc)
1466
{
1467
  CB_SYSCALL s;
1468
  SIM_DESC sd = CPU_STATE (current_cpu);
1469
  host_callback *cb = STATE_CALLBACK (sd);
1470
  int retval;
1471
  int threadno = current_cpu->threadno;
1472
 
1473
  current_cpu->syscalls++;
1474
 
1475
  CB_SYSCALL_INIT (&s);
1476
  s.func = callnum;
1477
  s.arg1 = arg1;
1478
  s.arg2 = arg2;
1479
  s.arg3 = arg3;
1480
 
1481
  if (callnum == TARGET_SYS_exit_group
1482
      || (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0))
1483
    {
1484
      if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1485
          & FLAG_CRIS_MISC_PROFILE_ALL)
1486
        dump_statistics (current_cpu);
1487
      sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
1488
    }
1489
 
1490
  s.p1 = (PTR) sd;
1491
  s.p2 = (PTR) current_cpu;
1492
  s.read_mem = syscall_read_mem;
1493
  s.write_mem = syscall_write_mem;
1494
 
1495
  current_cpu_for_cb_callback = current_cpu;
1496
 
1497
  if (cb_syscall (cb, &s) != CB_RC_OK)
1498
    {
1499
      abort ();
1500
      sim_io_eprintf (sd, "Break 13: invalid %d?  Returned %ld\n", callnum,
1501
                      s.result);
1502
      sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1503
    }
1504
 
1505
  retval = s.result == -1 ? -s.errcode : s.result;
1506
 
1507
  if (s.errcode != 0 && s.errcode == cb_host_to_target_errno (cb, ENOSYS))
1508
    {
1509
      /* If the generic simulator call said ENOSYS, then let's try the
1510
         ones we know ourselves.
1511
 
1512
         The convention is to provide *very limited* functionality on an
1513
         as-needed basis, only what's covered by the test-suite, tests
1514
         added when functionality changes and abort with a descriptive
1515
         message for *everything* else.  Where there's no test-case, we
1516
         just abort.  */
1517
      switch (callnum)
1518
        {
1519
        case 0:
1520
          /* It's a pretty safe bet that the "old setup() system call"
1521
             number will not be re-used; we can't say the same for higher
1522
             numbers.  We treat this simulator-generated call as "wait
1523
             forever"; we re-run this insn.  The wait is ended by a
1524
             callback.  Sanity check that this is the reason we got
1525
             here. */
1526
          if (current_cpu->thread_data == NULL
1527
              || (current_cpu->thread_data[threadno].pipe_write_fd == 0))
1528
            goto unimplemented_syscall;
1529
 
1530
          sim_pc_set (current_cpu, pc);
1531
          retval = arg1;
1532
          break;
1533
 
1534
        case TARGET_SYS_fcntl64:
1535
        case TARGET_SYS_fcntl:
1536
          switch (arg2)
1537
            {
1538
            case 1:
1539
              /* F_GETFD.
1540
                 Glibc checks stdin, stdout and stderr fd:s for
1541
                 close-on-exec security sanity.  We just need to provide a
1542
                 OK return value.  If we really need to have a
1543
                 close-on-exec flag true, we could just do a real fcntl
1544
                 here.  */
1545
              retval = 0;
1546
              break;
1547
 
1548
            case 2:
1549
              /* F_SETFD.  Just ignore attempts to set the close-on-exec
1550
                 flag.  */
1551
              retval = 0;
1552
              break;
1553
 
1554
            case 3:
1555
              /* F_GETFL.  Check for the special case for open+fdopen.  */
1556
              if (current_cpu->last_syscall == TARGET_SYS_open
1557
                  && arg1 == current_cpu->last_open_fd)
1558
                {
1559
                  retval = current_cpu->last_open_flags & TARGET_O_ACCMODE;
1560
                  break;
1561
                }
1562
              else if (arg1 == 0)
1563
                {
1564
                  /* Because we can't freopen fd:s 0, 1, 2 to mean
1565
                     something else than stdin, stdout and stderr
1566
                     (sim/common/syscall.c:cb_syscall special cases fd
1567
                     0, 1 and 2), we know what flags that we can
1568
                     sanely return for these fd:s.  */
1569
                  retval = TARGET_O_RDONLY;
1570
                  break;
1571
                }
1572
              else if (arg1 == 1 || arg1 == 2)
1573
                {
1574
                  retval = TARGET_O_WRONLY;
1575
                  break;
1576
                }
1577
              /* FALLTHROUGH */
1578
            default:
1579
              /* Nothing else is implemented.  */
1580
              retval
1581
                = cris_unknown_syscall (current_cpu, pc,
1582
                                        "Unimplemented %s syscall "
1583
                                        "(fd: 0x%lx: cmd: 0x%lx arg: "
1584
                                        "0x%lx)\n",
1585
                                        callnum == TARGET_SYS_fcntl
1586
                                        ? "fcntl" : "fcntl64",
1587
                                        (unsigned long) (USI) arg1,
1588
                                        (unsigned long) (USI) arg2,
1589
                                        (unsigned long) (USI) arg3);
1590
              break;
1591
            }
1592
          break;
1593
 
1594
        case TARGET_SYS_uname:
1595
          {
1596
            /* Fill in a few constants to appease glibc.  */
1597
            static char sim_utsname[6][65] =
1598
            {
1599
              "Linux",
1600
              "sim-target",
1601
              "2.6.27",
1602
              TARGET_UTSNAME,
1603
              "cris",           /* Overwritten below.  */
1604
              "localdomain"
1605
            };
1606
 
1607
            /* Having the hardware type in Linux equal to the bfd
1608
               printable name is deliberate: if you make config.guess
1609
               work on your Linux-type system the usual way, it
1610
               probably will; either the bfd printable_name or the
1611
               ambiguous arch_name.  */
1612
            strcpy (sim_utsname[4], STATE_ARCHITECTURE (sd)->printable_name);
1613
 
1614
            if ((s.write_mem) (cb, &s, arg1, (const char *) sim_utsname,
1615
                               sizeof (sim_utsname))
1616
                != sizeof (sim_utsname))
1617
              retval = -cb_host_to_target_errno (cb, EFAULT);
1618
            else
1619
              retval = 0;
1620
            break;
1621
          }
1622
 
1623
        case TARGET_SYS_geteuid32:
1624
          /* We tell the truth with these.  Maybe we shouldn't, but it
1625
             should match the "stat" information.  */
1626
          retval = geteuid ();
1627
          break;
1628
 
1629
        case TARGET_SYS_getuid32:
1630
          retval = getuid ();
1631
          break;
1632
 
1633
        case TARGET_SYS_getegid32:
1634
          retval = getegid ();
1635
          break;
1636
 
1637
        case TARGET_SYS_getgid32:
1638
          retval = getgid ();
1639
          break;
1640
 
1641
        case TARGET_SYS_brk:
1642
          /* Most often, we just return the argument, like the Linux
1643
             kernel.  */
1644
          retval = arg1;
1645
 
1646
          if (arg1 == 0)
1647
            retval = current_cpu->endbrk;
1648
          else if (arg1 <= current_cpu->endmem)
1649
            current_cpu->endbrk = arg1;
1650
          else
1651
            {
1652
              USI new_end = (arg1 + 8191) & ~8191;
1653
 
1654
              /* If the simulator wants to brk more than a certain very
1655
                 large amount, something is wrong.  FIXME: Return an error
1656
                 or abort?  Have command-line selectable?  */
1657
              if (new_end - current_cpu->endmem > SIM_MAX_ALLOC_CHUNK)
1658
                {
1659
                  current_cpu->endbrk = current_cpu->endmem;
1660
                  retval = current_cpu->endmem;
1661
                  break;
1662
                }
1663
 
1664
              sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1665
                               current_cpu->endmem,
1666
                               new_end - current_cpu->endmem,
1667
                               0, NULL, NULL);
1668
              current_cpu->endbrk = arg1;
1669
              current_cpu->endmem = new_end;
1670
            }
1671
          break;
1672
 
1673
        case TARGET_SYS_getpid:
1674
          /* Correct until CLONE_THREAD is implemented.  */
1675
          retval = current_cpu->thread_data == NULL
1676
            ? TARGET_PID
1677
            : TARGET_PID + current_cpu->thread_data[threadno].threadid;
1678
          break;
1679
 
1680
        case TARGET_SYS_getppid:
1681
          /* Correct until CLONE_THREAD is implemented.  */
1682
          retval = current_cpu->thread_data == NULL
1683
            ? TARGET_PID - 1
1684
            : (TARGET_PID
1685
               + current_cpu->thread_data[threadno].parent_threadid);
1686
          break;
1687
 
1688
        case TARGET_SYS_mmap2:
1689
          {
1690
            USI addr = arg1;
1691
            USI len = arg2;
1692
            USI prot = arg3;
1693
            USI flags = arg4;
1694
            USI fd = arg5;
1695
            USI pgoff = arg6;
1696
 
1697
            /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1698
               still masked away this bit, so let's just ignore
1699
               it.  */
1700
            flags &= ~TARGET_MAP_DENYWRITE;
1701
 
1702
            /* If the simulator wants to mmap more than the very large
1703
               limit, something is wrong.  FIXME: Return an error or
1704
               abort?  Have command-line selectable?  */
1705
            if (len > SIM_MAX_ALLOC_CHUNK)
1706
              {
1707
                retval = -cb_host_to_target_errno (cb, ENOMEM);
1708
                break;
1709
              }
1710
 
1711
            if ((prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)
1712
                 && (prot
1713
                     != (TARGET_PROT_READ
1714
                         | TARGET_PROT_WRITE
1715
                         | TARGET_PROT_EXEC))
1716
                 && (prot != (TARGET_PROT_READ | TARGET_PROT_EXEC))
1717
                 && prot != TARGET_PROT_READ)
1718
                || (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE)
1719
                    && flags != TARGET_MAP_PRIVATE
1720
                    && flags != (TARGET_MAP_ANONYMOUS
1721
                                 | TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1722
                    && flags != (TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1723
                    && flags != TARGET_MAP_SHARED)
1724
                || (fd != (USI) -1
1725
                    && prot != TARGET_PROT_READ
1726
                    && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1727
                    && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1728
                || (fd == (USI) -1 && pgoff != 0)
1729
                || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS)))
1730
              {
1731
                retval
1732
                  = cris_unknown_syscall (current_cpu, pc,
1733
                                                 "Unimplemented mmap2 call "
1734
                                                 "(0x%lx, 0x%lx, 0x%lx, "
1735
                                                 "0x%lx, 0x%lx, 0x%lx)\n",
1736
                                                 (unsigned long) arg1,
1737
                                                 (unsigned long) arg2,
1738
                                                 (unsigned long) arg3,
1739
                                                 (unsigned long) arg4,
1740
                                                 (unsigned long) arg5,
1741
                                                 (unsigned long) arg6);
1742
                break;
1743
              }
1744
            else if (fd != (USI) -1)
1745
              {
1746
                /* Map a file.  */
1747
 
1748
                USI newaddr;
1749
                USI pos;
1750
 
1751
                /* A non-aligned argument is allowed for files.  */
1752
                USI newlen = (len + 8191) & ~8191;
1753
 
1754
                /* We only support read, read|exec, and read|write,
1755
                   which we should already have checked.  Check again
1756
                   anyway.  */
1757
                if (prot != TARGET_PROT_READ
1758
                    && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1759
                    && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1760
                  abort ();
1761
 
1762
                if (flags & TARGET_MAP_FIXED)
1763
                  unmap_pages (sd, &current_cpu->highest_mmapped_page,
1764
                               addr, newlen);
1765
                else if (is_mapped (sd, &current_cpu->highest_mmapped_page,
1766
                                    addr, newlen))
1767
                  addr = 0;
1768
 
1769
                newaddr
1770
                  = create_map (sd, &current_cpu->highest_mmapped_page,
1771
                                addr != 0 || (flags & TARGET_MAP_FIXED)
1772
                                ? addr : -1,
1773
                                newlen);
1774
 
1775
                if (newaddr >= (USI) -8191)
1776
                  {
1777
                    abort ();
1778
                    retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1779
                    break;
1780
                  }
1781
 
1782
                /* We were asked for MAP_FIXED, but couldn't.  */
1783
                if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1784
                  {
1785
                    abort ();
1786
                    unmap_pages (sd, &current_cpu->highest_mmapped_page,
1787
                                 newaddr, newlen);
1788
                    retval = -cb_host_to_target_errno (cb, EINVAL);
1789
                    break;
1790
                  }
1791
 
1792
                /* Find the current position in the file.  */
1793
                s.func = TARGET_SYS_lseek;
1794
                s.arg1 = fd;
1795
                s.arg2 = 0;
1796
                s.arg3 = SEEK_CUR;
1797
                if (cb_syscall (cb, &s) != CB_RC_OK)
1798
                  abort ();
1799
                pos = s.result;
1800
 
1801
                if (s.result < 0)
1802
                  abort ();
1803
 
1804
                /* Move to the correct offset in the file.  */
1805
                s.func = TARGET_SYS_lseek;
1806
                s.arg1 = fd;
1807
                s.arg2 = pgoff*8192;
1808
                s.arg3 = SEEK_SET;
1809
                if (cb_syscall (cb, &s) != CB_RC_OK)
1810
                  abort ();
1811
 
1812
                if (s.result < 0)
1813
                  abort ();
1814
 
1815
                /* Use the standard read callback to read in "len"
1816
                   bytes.  */
1817
                s.func = TARGET_SYS_read;
1818
                s.arg1 = fd;
1819
                s.arg2 = newaddr;
1820
                s.arg3 = len;
1821
                if (cb_syscall (cb, &s) != CB_RC_OK)
1822
                  abort ();
1823
 
1824
                /* If the result is a page or more lesser than what
1825
                   was requested, something went wrong.  */
1826
                if (len >= 8192 && (USI) s.result <= len - 8192)
1827
                  abort ();
1828
 
1829
                /* After reading, we need to go back to the previous
1830
                   position in the file.  */
1831
                s.func = TARGET_SYS_lseek;
1832
                s.arg1 = fd;
1833
                s.arg2 = pos;
1834
                s.arg3 = SEEK_SET;
1835
                if (cb_syscall (cb, &s) != CB_RC_OK)
1836
                  abort ();
1837
                if (pos != (USI) s.result)
1838
                  abort ();
1839
 
1840
                retval = newaddr;
1841
              }
1842
            else
1843
              {
1844
                USI newlen = (len + 8191) & ~8191;
1845
                USI newaddr;
1846
 
1847
                if (flags & TARGET_MAP_FIXED)
1848
                  unmap_pages (sd, &current_cpu->highest_mmapped_page,
1849
                               addr, newlen);
1850
                else if (is_mapped (sd, &current_cpu->highest_mmapped_page,
1851
                                    addr, newlen))
1852
                  addr = 0;
1853
 
1854
                newaddr = create_map (sd, &current_cpu->highest_mmapped_page,
1855
                                      addr != 0 || (flags & TARGET_MAP_FIXED)
1856
                                      ? addr : -1,
1857
                                      newlen);
1858
 
1859
                if (newaddr >= (USI) -8191)
1860
                  retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1861
                else
1862
                  retval = newaddr;
1863
 
1864
                if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1865
                  {
1866
                    abort ();
1867
                    unmap_pages (sd, &current_cpu->highest_mmapped_page,
1868
                                 newaddr, newlen);
1869
                    retval = -cb_host_to_target_errno (cb, EINVAL);
1870
                    break;
1871
                  }
1872
              }
1873
            break;
1874
          }
1875
 
1876
        case TARGET_SYS_mprotect:
1877
          {
1878
            /* We only cover the case of linuxthreads mprotecting out
1879
               its stack guard page and of dynamic loading mprotecting
1880
               away the data (for some reason the whole library, then
1881
               mprotects away the data part and mmap-FIX:es it again.  */
1882
            USI addr = arg1;
1883
            USI len = arg2;
1884
            USI prot = arg3;
1885
 
1886
            if (prot != TARGET_PROT_NONE
1887
                || !is_mapped_only (sd, &current_cpu->highest_mmapped_page,
1888
                                    addr, (len + 8191) & ~8191))
1889
              {
1890
                retval
1891
                  = cris_unknown_syscall (current_cpu, pc,
1892
                                          "Unimplemented mprotect call "
1893
                                          "(0x%lx, 0x%lx, 0x%lx)\n",
1894
                                          (unsigned long) arg1,
1895
                                          (unsigned long) arg2,
1896
                                          (unsigned long) arg3);
1897
                break;
1898
              }
1899
 
1900
            /* Just ignore this.  We could make this equal to munmap,
1901
               but then we'd have to make sure no anon mmaps gets this
1902
               address before a subsequent MAP_FIXED mmap intended to
1903
               override it.  */
1904
            retval = 0;
1905
            break;
1906
          }
1907
 
1908
        case TARGET_SYS_ioctl:
1909
          {
1910
            /* We support only a very limited functionality: checking
1911
               stdout with TCGETS to perform the isatty function.  The
1912
               TCGETS ioctl isn't actually performed or the result used by
1913
               an isatty () caller in a "hello, world" program; only the
1914
               return value is then used.  Maybe we shouldn't care about
1915
               the environment of the simulator regarding isatty, but
1916
               that's been working before, in the xsim simulator.  */
1917
            if (arg2 == TARGET_TCGETS && arg1 == 1)
1918
              retval = isatty (1) ? 0 : cb_host_to_target_errno (cb, EINVAL);
1919
            else
1920
              retval = -cb_host_to_target_errno (cb, EINVAL);
1921
            break;
1922
          }
1923
 
1924
        case TARGET_SYS_munmap:
1925
          {
1926
            USI addr = arg1;
1927
            USI len = arg2;
1928
            USI result
1929
              = unmap_pages (sd, &current_cpu->highest_mmapped_page, addr,
1930
                             len);
1931
            retval = result != 0 ? -cb_host_to_target_errno (cb, result) : 0;
1932
            break;
1933
          }
1934
 
1935
        case TARGET_SYS_wait4:
1936
          {
1937
            int i;
1938
            USI pid = arg1;
1939
            USI saddr = arg2;
1940
            USI options = arg3;
1941
            USI rusagep = arg4;
1942
 
1943
            /* FIXME: We're not properly implementing __WCLONE, and we
1944
               don't really need the special casing so we might as well
1945
               make this general.  */
1946
            if ((!(pid == (USI) -1
1947
                   && options == (TARGET___WCLONE | TARGET_WNOHANG)
1948
                   && saddr != 0)
1949
                 && !(pid > 0
1950
                      && (options == TARGET___WCLONE
1951
                          || options == TARGET___WALL)))
1952
                || rusagep != 0
1953
                || current_cpu->thread_data == NULL)
1954
              {
1955
                retval
1956
                  = cris_unknown_syscall (current_cpu, pc,
1957
                                          "Unimplemented wait4 call "
1958
                                          "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1959
                                          (unsigned long) arg1,
1960
                                          (unsigned long) arg2,
1961
                                          (unsigned long) arg3,
1962
                                          (unsigned long) arg4);
1963
                break;
1964
              }
1965
 
1966
            if (pid == (USI) -1)
1967
              for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1968
                {
1969
                  if (current_cpu->thread_data[threadno].threadid
1970
                      == current_cpu->thread_data[i].parent_threadid
1971
                      && current_cpu->thread_data[i].threadid != 0
1972
                      && current_cpu->thread_data[i].cpu_context == NULL)
1973
                    {
1974
                      /* A zombied child.  Get the exit value and clear the
1975
                         zombied entry so it will be reused.  */
1976
                      sim_core_write_unaligned_4 (current_cpu, pc, 0, saddr,
1977
                                                  current_cpu
1978
                                                  ->thread_data[i].exitval);
1979
                      retval
1980
                        = current_cpu->thread_data[i].threadid + TARGET_PID;
1981
                      memset (&current_cpu->thread_data[i], 0,
1982
                              sizeof (current_cpu->thread_data[i]));
1983
                      goto outer_break;
1984
                    }
1985
                }
1986
            else
1987
              {
1988
                /* We're waiting for a specific PID.  If we don't find
1989
                   it zombied on this run, rerun the syscall.  */
1990
                for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1991
                  if (pid == current_cpu->thread_data[i].threadid + TARGET_PID
1992
                      && current_cpu->thread_data[i].cpu_context == NULL)
1993
                    {
1994
                      if (saddr != 0)
1995
                        /* Get the exit value if the caller wants it.  */
1996
                        sim_core_write_unaligned_4 (current_cpu, pc, 0,
1997
                                                    saddr,
1998
                                                    current_cpu
1999
                                                    ->thread_data[i]
2000
                                                    .exitval);
2001
 
2002
                      retval
2003
                        = current_cpu->thread_data[i].threadid + TARGET_PID;
2004
                      memset (&current_cpu->thread_data[i], 0,
2005
                              sizeof (current_cpu->thread_data[i]));
2006
 
2007
                      goto outer_break;
2008
                    }
2009
 
2010
                sim_pc_set (current_cpu, pc);
2011
              }
2012
 
2013
            retval = -cb_host_to_target_errno (cb, ECHILD);
2014
          outer_break:
2015
            break;
2016
          }
2017
 
2018
        case TARGET_SYS_rt_sigaction:
2019
          {
2020
            USI signum = arg1;
2021
            USI old_sa = arg3;
2022
            USI new_sa = arg2;
2023
 
2024
            /* The kernel says:
2025
               struct sigaction {
2026
                        __sighandler_t sa_handler;
2027
                        unsigned long sa_flags;
2028
                        void (*sa_restorer)(void);
2029
                        sigset_t sa_mask;
2030
               }; */
2031
 
2032
            if (old_sa != 0)
2033
              {
2034
                sim_core_write_unaligned_4 (current_cpu, pc, 0, old_sa + 0,
2035
                                            current_cpu->sighandler[signum]);
2036
                sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 4, 0);
2037
                sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 8, 0);
2038
 
2039
                /* We'll assume _NSIG_WORDS is 2 for the kernel.  */
2040
                sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 12, 0);
2041
                sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 16, 0);
2042
              }
2043
            if (new_sa != 0)
2044
              {
2045
                USI target_sa_handler
2046
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa);
2047
                USI target_sa_flags
2048
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 4);
2049
                USI target_sa_restorer
2050
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 8);
2051
                USI target_sa_mask_low
2052
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 12);
2053
                USI target_sa_mask_high
2054
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 16);
2055
 
2056
                /* We won't interrupt a syscall so we won't restart it,
2057
                   but a signal(2) call ends up syscalling rt_sigaction
2058
                   with this flag, so we have to handle it.  The
2059
                   sa_restorer field contains garbage when not
2060
                   TARGET_SA_RESTORER, so don't look at it.  For the
2061
                   time being, we don't nest sighandlers, so we
2062
                   ignore the sa_mask, which simplifies things.  */
2063
                if ((target_sa_flags != 0
2064
                     && target_sa_flags != TARGET_SA_RESTART
2065
                     && target_sa_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO))
2066
                    || target_sa_handler == 0)
2067
                  {
2068
                    retval
2069
                      = cris_unknown_syscall (current_cpu, pc,
2070
                                              "Unimplemented rt_sigaction "
2071
                                              "syscall "
2072
                                              "(0x%lx, 0x%lx: "
2073
                                              "[0x%x, 0x%x, 0x%x, "
2074
                                              "{0x%x, 0x%x}], 0x%lx)\n",
2075
                                              (unsigned long) arg1,
2076
                                              (unsigned long) arg2,
2077
                                              target_sa_handler,
2078
                                              target_sa_flags,
2079
                                              target_sa_restorer,
2080
                                              target_sa_mask_low,
2081
                                              target_sa_mask_high,
2082
                                              (unsigned long) arg3);
2083
                    break;
2084
                  }
2085
 
2086
                current_cpu->sighandler[signum] = target_sa_handler;
2087
 
2088
                /* Because we may have unblocked signals, one may now be
2089
                   pending, if there are threads, that is.  */
2090
                if (current_cpu->thread_data)
2091
                  current_cpu->thread_data[threadno].sigpending = 1;
2092
              }
2093
            retval = 0;
2094
            break;
2095
          }
2096
 
2097
        case TARGET_SYS_mremap:
2098
          {
2099
            USI addr = arg1;
2100
            USI old_len = arg2;
2101
            USI new_len = arg3;
2102
            USI flags = arg4;
2103
            USI new_addr = arg5;
2104
            USI mapped_addr;
2105
 
2106
            if (new_len == old_len)
2107
              /* The program and/or library is possibly confused but
2108
                 this is a valid call.  Happens with ipps-1.40 on file
2109
                 svs_all.  */
2110
              retval = addr;
2111
            else if (new_len < old_len)
2112
              {
2113
                /* Shrinking is easy.  */
2114
                if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
2115
                                 addr + new_len, old_len - new_len) != 0)
2116
                  retval = -cb_host_to_target_errno (cb, EINVAL);
2117
                else
2118
                  retval = addr;
2119
              }
2120
            else if (! is_mapped (sd, &current_cpu->highest_mmapped_page,
2121
                                  addr + old_len, new_len - old_len))
2122
              {
2123
                /* If the extension isn't mapped, we can just add it.  */
2124
                mapped_addr
2125
                  = create_map (sd, &current_cpu->highest_mmapped_page,
2126
                                addr + old_len, new_len - old_len);
2127
 
2128
                if (mapped_addr > (USI) -8192)
2129
                  retval = -cb_host_to_target_errno (cb, -(SI) mapped_addr);
2130
                else
2131
                  retval = addr;
2132
              }
2133
            else if (flags & TARGET_MREMAP_MAYMOVE)
2134
              {
2135
                /* Create a whole new map and copy the contents
2136
                   block-by-block there.  We ignore the new_addr argument
2137
                   for now.  */
2138
                char buf[8192];
2139
                USI prev_addr = addr;
2140
                USI prev_len = old_len;
2141
 
2142
                mapped_addr
2143
                  = create_map (sd, &current_cpu->highest_mmapped_page,
2144
                                -1, new_len);
2145
 
2146
                if (mapped_addr > (USI) -8192)
2147
                  {
2148
                    retval = -cb_host_to_target_errno (cb, -(SI) new_addr);
2149
                    break;
2150
                  }
2151
 
2152
                retval = mapped_addr;
2153
 
2154
                for (; old_len > 0;
2155
                     old_len -= 8192, mapped_addr += 8192, addr += 8192)
2156
                  {
2157
                    if (sim_core_read_buffer (sd, current_cpu, read_map, buf,
2158
                                              addr, 8192) != 8192
2159
                        || sim_core_write_buffer (sd, current_cpu, 0, buf,
2160
                                                  mapped_addr, 8192) != 8192)
2161
                      abort ();
2162
                  }
2163
 
2164
                if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
2165
                                 prev_addr, prev_len) != 0)
2166
                  abort ();
2167
              }
2168
            else
2169
              retval = -cb_host_to_target_errno (cb, -ENOMEM);
2170
            break;
2171
          }
2172
 
2173
        case TARGET_SYS_poll:
2174
          {
2175
            int npollfds = arg2;
2176
            int timeout = arg3;
2177
            SI ufds = arg1;
2178
            SI fd = -1;
2179
            HI events = -1;
2180
            HI revents = 0;
2181
            struct stat buf;
2182
            int i;
2183
 
2184
            /* The kernel says:
2185
                struct pollfd {
2186
                     int fd;
2187
                     short events;
2188
                     short revents;
2189
                }; */
2190
 
2191
            /* Check that this is the expected poll call from
2192
               linuxthreads/manager.c; we don't support anything else.
2193
               Remember, fd == 0 isn't supported.  */
2194
            if (npollfds != 1
2195
                || ((fd = sim_core_read_unaligned_4 (current_cpu, pc,
2196
                                                     0, ufds)) <= 0)
2197
                || ((events = sim_core_read_unaligned_2 (current_cpu, pc,
2198
                                                         0, ufds + 4))
2199
                    != TARGET_POLLIN)
2200
                || ((cb->fstat) (cb, fd, &buf) != 0
2201
                    || (buf.st_mode & S_IFIFO) == 0)
2202
                || current_cpu->thread_data == NULL)
2203
              {
2204
                retval
2205
                  = cris_unknown_syscall (current_cpu, pc,
2206
                                          "Unimplemented poll syscall "
2207
                                          "(0x%lx: [0x%x, 0x%x, x], "
2208
                                          "0x%lx, 0x%lx)\n",
2209
                                          (unsigned long) arg1, fd, events,
2210
                                          (unsigned long) arg2,
2211
                                          (unsigned long) arg3);
2212
                break;
2213
              }
2214
 
2215
            retval = 0;
2216
 
2217
            /* Iterate over threads; find a marker that a writer is
2218
               sleeping, waiting for a reader.  */
2219
            for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
2220
              if (current_cpu->thread_data[i].cpu_context != NULL
2221
                  && current_cpu->thread_data[i].pipe_read_fd == fd)
2222
                {
2223
                  revents = TARGET_POLLIN;
2224
                  retval = 1;
2225
                  break;
2226
                }
2227
 
2228
            /* Timeout decreases with whatever time passed between the
2229
               last syscall and this.  That's not exactly right for the
2230
               first call, but it's close enough that it isn't
2231
               worthwhile to complicate matters by making that a special
2232
               case.  */
2233
            timeout
2234
              -= (TARGET_TIME_MS (current_cpu)
2235
                  - (current_cpu->thread_data[threadno].last_execution));
2236
 
2237
            /* Arrange to repeat this syscall until timeout or event,
2238
               decreasing timeout at each iteration.  */
2239
            if (timeout > 0 && revents == 0)
2240
              {
2241
                bfd_byte timeout_buf[4];
2242
 
2243
                bfd_putl32 (timeout, timeout_buf);
2244
                (*CPU_REG_STORE (current_cpu)) (current_cpu,
2245
                                                H_GR_R12, timeout_buf, 4);
2246
                sim_pc_set (current_cpu, pc);
2247
                retval = arg1;
2248
                break;
2249
              }
2250
 
2251
            sim_core_write_unaligned_2 (current_cpu, pc, 0, ufds + 4 + 2,
2252
                                        revents);
2253
            break;
2254
          }
2255
 
2256
        case TARGET_SYS_time:
2257
          {
2258
            retval = (int) (*cb->time) (cb, 0L);
2259
 
2260
            /* At time of this writing, CB_SYSCALL_time doesn't do the
2261
               part of setting *arg1 to the return value.  */
2262
            if (arg1)
2263
              sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, retval);
2264
            break;
2265
          }
2266
 
2267
        case TARGET_SYS_gettimeofday:
2268
          if (arg1 != 0)
2269
            {
2270
              USI ts = TARGET_TIME (current_cpu);
2271
              USI tms = TARGET_TIME_MS (current_cpu);
2272
 
2273
              /* First dword is seconds since TARGET_EPOCH.  */
2274
              sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, ts);
2275
 
2276
              /* Second dword is microseconds.  */
2277
              sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1 + 4,
2278
                                          (tms % 1000) * 1000);
2279
            }
2280
          if (arg2 != 0)
2281
            {
2282
              /* Time-zone info is always cleared.  */
2283
              sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, 0);
2284
              sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, 0);
2285
            }
2286
          retval = 0;
2287
          break;
2288
 
2289
        case TARGET_SYS_llseek:
2290
          {
2291
            /* If it fits, tweak parameters to fit the "generic" 32-bit
2292
               lseek and use that.  */
2293
            SI fd = arg1;
2294
            SI offs_hi = arg2;
2295
            SI offs_lo = arg3;
2296
            SI resultp = arg4;
2297
            SI whence = arg5;
2298
            retval = 0;
2299
 
2300
            if (!((offs_hi == 0 && offs_lo >= 0)
2301
                  || (offs_hi == -1 &&  offs_lo < 0)))
2302
              {
2303
                retval
2304
                  = cris_unknown_syscall (current_cpu, pc,
2305
                                          "Unimplemented llseek offset,"
2306
                                          " fd %d: 0x%x:0x%x\n",
2307
                                          fd, (unsigned) arg2,
2308
                                          (unsigned) arg3);
2309
                break;
2310
              }
2311
 
2312
            s.func = TARGET_SYS_lseek;
2313
            s.arg2 = offs_lo;
2314
            s.arg3 = whence;
2315
            if (cb_syscall (cb, &s) != CB_RC_OK)
2316
              {
2317
                sim_io_eprintf (sd, "Break 13: invalid %d?  Returned %ld\n", callnum,
2318
                                s.result);
2319
                sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
2320
              }
2321
            if (s.result < 0)
2322
              retval = -s.errcode;
2323
            else
2324
              {
2325
                sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp,
2326
                                            s.result);
2327
                sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp + 4,
2328
                                            s.result < 0 ? -1 : 0);
2329
              }
2330
            break;
2331
          }
2332
 
2333
          /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2334
              where:
2335
             struct iovec {
2336
               void  *iov_base;    Starting address
2337
               size_t iov_len;     Number of bytes to transfer
2338
             }; */
2339
        case TARGET_SYS_writev:
2340
          {
2341
            SI fd = arg1;
2342
            SI iov = arg2;
2343
            SI iovcnt = arg3;
2344
            SI retcnt = 0;
2345
            int i;
2346
 
2347
            /* We'll ignore strict error-handling and just do multiple write calls.  */
2348
            for (i = 0; i < iovcnt; i++)
2349
              {
2350
                int sysret;
2351
                USI iov_base
2352
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2353
                                               iov + 8*i);
2354
                USI iov_len
2355
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2356
                                               iov + 8*i + 4);
2357
 
2358
                s.func = TARGET_SYS_write;
2359
                s.arg1 = fd;
2360
                s.arg2 = iov_base;
2361
                s.arg3 = iov_len;
2362
 
2363
                if (cb_syscall (cb, &s) != CB_RC_OK)
2364
                  abort ();
2365
                sysret = s.result == -1 ? -s.errcode : s.result;
2366
 
2367
                if (sysret != iov_len)
2368
                  {
2369
                    if (i != 0)
2370
                      abort ();
2371
                    retcnt = sysret;
2372
                    break;
2373
                  }
2374
 
2375
                retcnt += iov_len;
2376
              }
2377
 
2378
            retval = retcnt;
2379
          }
2380
          break;
2381
 
2382
        /* This one does have a generic callback function, but at the time
2383
           of this writing, cb_syscall does not have code for it, and we
2384
           need target-specific code for the threads implementation
2385
           anyway.  */
2386
        case TARGET_SYS_kill:
2387
          {
2388
            USI pid = arg1;
2389
            USI sig = arg2;
2390
 
2391
            retval = 0;
2392
 
2393
            /* At kill(2), glibc sets signal masks such that the thread
2394
               machinery is initialized.  Still, there is and was only
2395
               one thread.  */
2396
            if (current_cpu->max_threadid == 0)
2397
              {
2398
                if (pid != TARGET_PID)
2399
                  {
2400
                    retval = -cb_host_to_target_errno (cb, EPERM);
2401
                    break;
2402
                  }
2403
 
2404
                /* FIXME: Signal infrastructure (target-to-sim mapping).  */
2405
                if (sig == TARGET_SIGABRT)
2406
                  /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2407
                     the end-point for failing GCC test-cases.  */
2408
                  sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2409
                                   SIM_SIGABRT);
2410
                else
2411
                  {
2412
                    sim_io_eprintf (sd, "Unimplemented signal: %d\n", sig);
2413
                    sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2414
                                     SIM_SIGILL);
2415
                  }
2416
 
2417
                /* This will not be reached.  */
2418
                abort ();
2419
              }
2420
            else
2421
              retval = deliver_signal (current_cpu, sig, pid);
2422
            break;
2423
          }
2424
 
2425
        case TARGET_SYS_rt_sigprocmask:
2426
          {
2427
            int i;
2428
            USI how = arg1;
2429
            USI newsetp = arg2;
2430
            USI oldsetp = arg3;
2431
 
2432
            if (how != TARGET_SIG_BLOCK
2433
                && how != TARGET_SIG_SETMASK
2434
                && how != TARGET_SIG_UNBLOCK)
2435
              {
2436
                retval
2437
                  = cris_unknown_syscall (current_cpu, pc,
2438
                                          "Unimplemented rt_sigprocmask "
2439
                                          "syscall (0x%x, 0x%x, 0x%x)\n",
2440
                                          arg1, arg2, arg3);
2441
                break;
2442
              }
2443
 
2444
            if (newsetp)
2445
              {
2446
                USI set_low
2447
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2448
                                               newsetp);
2449
                USI set_high
2450
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2451
                                               newsetp + 4);
2452
 
2453
                /* The sigmask is kept in the per-thread data, so we may
2454
                   need to create the first one.  */
2455
                if (current_cpu->thread_data == NULL)
2456
                  make_first_thread (current_cpu);
2457
 
2458
                if (how == TARGET_SIG_SETMASK)
2459
                  for (i = 0; i < 64; i++)
2460
                    current_cpu->thread_data[threadno].sigdata[i].blocked = 0;
2461
 
2462
                for (i = 0; i < 32; i++)
2463
                  if ((set_low & (1 << i)))
2464
                    current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2465
                      = (how != TARGET_SIG_UNBLOCK);
2466
 
2467
                for (i = 0; i < 31; i++)
2468
                  if ((set_high & (1 << i)))
2469
                    current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2470
                      = (how != TARGET_SIG_UNBLOCK);
2471
 
2472
                /* The mask changed, so a signal may be unblocked for
2473
                   execution.  */
2474
                current_cpu->thread_data[threadno].sigpending = 1;
2475
              }
2476
 
2477
            if (oldsetp != 0)
2478
              {
2479
                USI set_low = 0;
2480
                USI set_high = 0;
2481
 
2482
                for (i = 0; i < 32; i++)
2483
                  if (current_cpu->thread_data[threadno]
2484
                      .sigdata[i + 1].blocked)
2485
                    set_low |= 1 << i;
2486
                for (i = 0; i < 31; i++)
2487
                  if (current_cpu->thread_data[threadno]
2488
                      .sigdata[i + 33].blocked)
2489
                    set_high |= 1 << i;
2490
 
2491
                sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 0, set_low);
2492
                sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 4, set_high);
2493
              }
2494
 
2495
            retval = 0;
2496
            break;
2497
          }
2498
 
2499
        case TARGET_SYS_sigreturn:
2500
          {
2501
            int i;
2502
            bfd_byte regbuf[4];
2503
            int was_sigsuspended;
2504
 
2505
            if (current_cpu->thread_data == NULL
2506
                /* The CPU context is saved with the simulator data, not
2507
                   on the stack as in the real world.  */
2508
                || (current_cpu->thread_data[threadno].cpu_context_atsignal
2509
                    == NULL))
2510
              {
2511
                retval
2512
                  = cris_unknown_syscall (current_cpu, pc,
2513
                                          "Invalid sigreturn syscall: "
2514
                                          "no signal handler active "
2515
                                          "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2516
                                          "0x%lx, 0x%lx)\n",
2517
                                          (unsigned long) arg1,
2518
                                          (unsigned long) arg2,
2519
                                          (unsigned long) arg3,
2520
                                          (unsigned long) arg4,
2521
                                          (unsigned long) arg5,
2522
                                          (unsigned long) arg6);
2523
                break;
2524
              }
2525
 
2526
            was_sigsuspended
2527
              = current_cpu->thread_data[threadno].sigsuspended;
2528
 
2529
            /* Restore the sigmask, either from the stack copy made when
2530
               the sighandler was called, or from the saved state
2531
               specifically for sigsuspend(2).  */
2532
            if (was_sigsuspended)
2533
              {
2534
                current_cpu->thread_data[threadno].sigsuspended = 0;
2535
                for (i = 0; i < 64; i++)
2536
                  current_cpu->thread_data[threadno].sigdata[i].blocked
2537
                    = current_cpu->thread_data[threadno]
2538
                    .sigdata[i].blocked_suspendsave;
2539
              }
2540
            else
2541
              {
2542
                USI sp;
2543
                USI set_low;
2544
                USI set_high;
2545
 
2546
                (*CPU_REG_FETCH (current_cpu)) (current_cpu,
2547
                                            H_GR_SP, regbuf, 4);
2548
                sp = bfd_getl32 (regbuf);
2549
                set_low
2550
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp);
2551
                set_high
2552
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp + 4);
2553
 
2554
                for (i = 0; i < 32; i++)
2555
                  current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2556
                    = (set_low & (1 << i)) != 0;
2557
                for (i = 0; i < 31; i++)
2558
                  current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2559
                    = (set_high & (1 << i)) != 0;
2560
              }
2561
 
2562
            /* The mask changed, so a signal may be unblocked for
2563
               execution.  */
2564
            current_cpu->thread_data[threadno].sigpending = 1;
2565
 
2566
            memcpy (&current_cpu->cpu_data_placeholder,
2567
                    current_cpu->thread_data[threadno].cpu_context_atsignal,
2568
                    current_cpu->thread_cpu_data_size);
2569
            free (current_cpu->thread_data[threadno].cpu_context_atsignal);
2570
            current_cpu->thread_data[threadno].cpu_context_atsignal = NULL;
2571
 
2572
            /* The return value must come from the saved R10.  */
2573
            (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, regbuf, 4);
2574
            retval = bfd_getl32 (regbuf);
2575
 
2576
            /* We must also break the "sigsuspension loop".  */
2577
            if (was_sigsuspended)
2578
              sim_pc_set (current_cpu, sim_pc_get (current_cpu) + 2);
2579
            break;
2580
          }
2581
 
2582
        case TARGET_SYS_rt_sigsuspend:
2583
          {
2584
            USI newsetp = arg1;
2585
            USI setsize = arg2;
2586
 
2587
            if (setsize != 8)
2588
              {
2589
                retval
2590
                  = cris_unknown_syscall (current_cpu, pc,
2591
                                          "Unimplemented rt_sigsuspend syscall"
2592
                                          " arguments (0x%lx, 0x%lx)\n",
2593
                                          (unsigned long) arg1,
2594
                                          (unsigned long) arg2);
2595
                break;
2596
              }
2597
 
2598
            /* Don't change the signal mask if we're already in
2599
               sigsuspend state (i.e. this syscall is a rerun).  */
2600
            else if (!current_cpu->thread_data[threadno].sigsuspended)
2601
              {
2602
                USI set_low
2603
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2604
                                               newsetp);
2605
                USI set_high
2606
                  = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2607
                                               newsetp + 4);
2608
                int i;
2609
 
2610
                /* Save the current sigmask and insert the user-supplied
2611
                   one.  */
2612
                for (i = 0; i < 32; i++)
2613
                  {
2614
                    current_cpu->thread_data[threadno]
2615
                      .sigdata[i + 1].blocked_suspendsave
2616
                      = current_cpu->thread_data[threadno]
2617
                      .sigdata[i + 1].blocked;
2618
 
2619
                    current_cpu->thread_data[threadno]
2620
                      .sigdata[i + 1].blocked = (set_low & (1 << i)) != 0;
2621
                  }
2622
                for (i = 0; i < 31; i++)
2623
                  {
2624
                    current_cpu->thread_data[threadno]
2625
                      .sigdata[i + 33].blocked_suspendsave
2626
                      = current_cpu->thread_data[threadno]
2627
                      .sigdata[i + 33].blocked;
2628
                    current_cpu->thread_data[threadno]
2629
                      .sigdata[i + 33].blocked = (set_high & (1 << i)) != 0;
2630
                  }
2631
 
2632
                current_cpu->thread_data[threadno].sigsuspended = 1;
2633
 
2634
                /* The mask changed, so a signal may be unblocked for
2635
                   execution. */
2636
                current_cpu->thread_data[threadno].sigpending = 1;
2637
              }
2638
 
2639
            /* Because we don't use arg1 (newsetp) when this syscall is
2640
               rerun, it doesn't matter that we overwrite it with the
2641
               (constant) return value.  */
2642
            retval = -cb_host_to_target_errno (cb, EINTR);
2643
            sim_pc_set (current_cpu, pc);
2644
            break;
2645
          }
2646
 
2647
          /* Add case labels here for other syscalls using the 32-bit
2648
             "struct stat", provided they have a corresponding simulator
2649
             function of course.  */
2650
        case TARGET_SYS_stat:
2651
        case TARGET_SYS_fstat:
2652
          {
2653
            /* As long as the infrastructure doesn't cache anything
2654
               related to the stat mapping, this trick gets us a dual
2655
               "struct stat"-type mapping in the least error-prone way.  */
2656
            const char *saved_map = cb->stat_map;
2657
            CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
2658
 
2659
            cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_stat32_map;
2660
            cb->stat_map = stat32_map;
2661
 
2662
            if (cb_syscall (cb, &s) != CB_RC_OK)
2663
              {
2664
                abort ();
2665
                sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2666
                                 SIM_SIGILL);
2667
              }
2668
            retval = s.result == -1 ? -s.errcode : s.result;
2669
 
2670
            cb->stat_map = saved_map;
2671
            cb->syscall_map = saved_syscall_map;
2672
            break;
2673
          }
2674
 
2675
        case TARGET_SYS_getcwd:
2676
          {
2677
            USI buf = arg1;
2678
            USI size = arg2;
2679
 
2680
            char *cwd = xmalloc (SIM_PATHMAX);
2681
            if (cwd != getcwd (cwd, SIM_PATHMAX))
2682
              abort ();
2683
 
2684
            /* FIXME: When and if we support chdir, we need something
2685
               a bit more elaborate.  */
2686
            if (simulator_sysroot[0] != '\0')
2687
              strcpy (cwd, "/");
2688
 
2689
            retval = -cb_host_to_target_errno (cb, ERANGE);
2690
            if (strlen (cwd) + 1 <= size)
2691
              {
2692
                retval = strlen (cwd) + 1;
2693
                if (sim_core_write_buffer (sd, current_cpu, 0, cwd,
2694
                                           buf, retval)
2695
                    != (unsigned int) retval)
2696
                  retval = -cb_host_to_target_errno (cb, EFAULT);
2697
              }
2698
            free (cwd);
2699
            break;
2700
          }
2701
 
2702
        case TARGET_SYS_access:
2703
          {
2704
            SI path = arg1;
2705
            SI mode = arg2;
2706
            char *pbuf = xmalloc (SIM_PATHMAX);
2707
            int i;
2708
            int o = 0;
2709
            int hmode = 0;
2710
 
2711
            if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2712
              {
2713
                strcpy (pbuf, simulator_sysroot);
2714
                o += strlen (simulator_sysroot);
2715
              }
2716
 
2717
            for (i = 0; i + o < SIM_PATHMAX; i++)
2718
              {
2719
                pbuf[i + o]
2720
                  = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2721
                if (pbuf[i + o] == 0)
2722
                  break;
2723
              }
2724
 
2725
            if (i + o == SIM_PATHMAX)
2726
              {
2727
                retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2728
                break;
2729
              }
2730
 
2731
            /* Assert that we don't get calls for files for which we
2732
               don't have support.  */
2733
            if (strncmp (pbuf + strlen (simulator_sysroot),
2734
                         "/proc/", 6) == 0)
2735
              abort ();
2736
#define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2737
            X_AFLAG (R_OK);
2738
            X_AFLAG (W_OK);
2739
            X_AFLAG (X_OK);
2740
            X_AFLAG (F_OK);
2741
#undef X_AFLAG
2742
 
2743
            if (access (pbuf, hmode) != 0)
2744
              retval = -cb_host_to_target_errno (cb, errno);
2745
            else
2746
              retval = 0;
2747
 
2748
            free (pbuf);
2749
            break;
2750
          }
2751
 
2752
        case TARGET_SYS_readlink:
2753
          {
2754
            SI path = arg1;
2755
            SI buf = arg2;
2756
            SI bufsiz = arg3;
2757
            char *pbuf = xmalloc (SIM_PATHMAX);
2758
            char *lbuf = xmalloc (SIM_PATHMAX);
2759
            char *lbuf_alloc = lbuf;
2760
            int nchars = -1;
2761
            int i;
2762
            int o = 0;
2763
 
2764
            if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2765
              {
2766
                strcpy (pbuf, simulator_sysroot);
2767
                o += strlen (simulator_sysroot);
2768
              }
2769
 
2770
            for (i = 0; i + o < SIM_PATHMAX; i++)
2771
              {
2772
                pbuf[i + o]
2773
                  = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2774
                if (pbuf[i + o] == 0)
2775
                  break;
2776
              }
2777
 
2778
            if (i + o == SIM_PATHMAX)
2779
              {
2780
                retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2781
                break;
2782
              }
2783
 
2784
            /* Intervene calls for certain files expected in the target
2785
               proc file system.  */
2786
            if (strcmp (pbuf + strlen (simulator_sysroot),
2787
                        "/proc/" XSTRING (TARGET_PID) "/exe") == 0)
2788
              {
2789
                char *argv0
2790
                  = (STATE_PROG_ARGV (sd) != NULL
2791
                     ? *STATE_PROG_ARGV (sd) : NULL);
2792
 
2793
                if (argv0 == NULL || *argv0 == '.')
2794
                  {
2795
                    retval
2796
                      = cris_unknown_syscall (current_cpu, pc,
2797
                                              "Unimplemented readlink syscall "
2798
                                              "(0x%lx: [\"%s\"], 0x%lx)\n",
2799
                                              (unsigned long) arg1, pbuf,
2800
                                              (unsigned long) arg2);
2801
                    break;
2802
                  }
2803
                else if (*argv0 == '/')
2804
                  {
2805
                    if (strncmp (simulator_sysroot, argv0,
2806
                                 strlen (simulator_sysroot)) == 0)
2807
                      argv0 += strlen (simulator_sysroot);
2808
 
2809
                    strcpy (lbuf, argv0);
2810
                    nchars = strlen (argv0) + 1;
2811
                  }
2812
                else
2813
                  {
2814
                    if (getcwd (lbuf, SIM_PATHMAX) != NULL
2815
                        && strlen (lbuf) + 2 + strlen (argv0) < SIM_PATHMAX)
2816
                      {
2817
                        if (strncmp (simulator_sysroot, lbuf,
2818
                                     strlen (simulator_sysroot)) == 0)
2819
                          lbuf += strlen (simulator_sysroot);
2820
 
2821
                        strcat (lbuf, "/");
2822
                        strcat (lbuf, argv0);
2823
                        nchars = strlen (lbuf) + 1;
2824
                      }
2825
                    else
2826
                      abort ();
2827
                  }
2828
              }
2829
            else
2830
              nchars = readlink (pbuf, lbuf, SIM_PATHMAX);
2831
 
2832
            /* We trust that the readlink result returns a *relative*
2833
               link, or one already adjusted for the file-path-prefix.
2834
               (We can't generally tell the difference, so we go with
2835
               the easiest decision; no adjustment.)  */
2836
 
2837
            if (nchars == -1)
2838
              {
2839
                retval = -cb_host_to_target_errno (cb, errno);
2840
                break;
2841
              }
2842
 
2843
            if (bufsiz < nchars)
2844
              nchars = bufsiz;
2845
 
2846
            if (sim_core_write_buffer (sd, current_cpu, write_map, lbuf,
2847
                                       buf, nchars) != (unsigned int) nchars)
2848
              retval = -cb_host_to_target_errno (cb, EFAULT);
2849
            else
2850
              retval = nchars;
2851
 
2852
            free (pbuf);
2853
            free (lbuf_alloc);
2854
            break;
2855
          }
2856
 
2857
        case TARGET_SYS_sched_getscheduler:
2858
          {
2859
            USI pid = arg1;
2860
 
2861
            /* FIXME: Search (other) existing threads.  */
2862
            if (pid != 0 && pid != TARGET_PID)
2863
              retval = -cb_host_to_target_errno (cb, ESRCH);
2864
            else
2865
              retval = TARGET_SCHED_OTHER;
2866
            break;
2867
          }
2868
 
2869
        case TARGET_SYS_sched_getparam:
2870
          {
2871
            USI pid = arg1;
2872
            USI paramp = arg2;
2873
 
2874
            /* The kernel says:
2875
               struct sched_param {
2876
                        int sched_priority;
2877
               }; */
2878
 
2879
            if (pid != 0 && pid != TARGET_PID)
2880
              retval = -cb_host_to_target_errno (cb, ESRCH);
2881
            else
2882
              {
2883
                /* FIXME: Save scheduler setting before threads are
2884
                   created too.  */
2885
                sim_core_write_unaligned_4 (current_cpu, pc, 0, paramp,
2886
                                            current_cpu->thread_data != NULL
2887
                                            ? (current_cpu
2888
                                               ->thread_data[threadno]
2889
                                               .priority)
2890
                                            : 0);
2891
                retval = 0;
2892
              }
2893
            break;
2894
          }
2895
 
2896
        case TARGET_SYS_sched_setparam:
2897
          {
2898
            USI pid = arg1;
2899
            USI paramp = arg2;
2900
 
2901
            if ((pid != 0 && pid != TARGET_PID)
2902
                || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2903
                                              paramp) != 0)
2904
              retval = -cb_host_to_target_errno (cb, EINVAL);
2905
            else
2906
              retval = 0;
2907
            break;
2908
          }
2909
 
2910
        case TARGET_SYS_sched_setscheduler:
2911
          {
2912
            USI pid = arg1;
2913
            USI policy = arg2;
2914
            USI paramp = arg3;
2915
 
2916
            if ((pid != 0 && pid != TARGET_PID)
2917
                || policy != TARGET_SCHED_OTHER
2918
                || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2919
                                              paramp) != 0)
2920
              retval = -cb_host_to_target_errno (cb, EINVAL);
2921
            else
2922
              /* FIXME: Save scheduler setting to be read in later
2923
                 sched_getparam calls.  */
2924
              retval = 0;
2925
            break;
2926
          }
2927
 
2928
        case TARGET_SYS_sched_yield:
2929
          /* We reschedule to the next thread after a syscall anyway, so
2930
             we don't have to do anything here than to set the return
2931
             value.  */
2932
          retval = 0;
2933
          break;
2934
 
2935
        case TARGET_SYS_sched_get_priority_min:
2936
        case TARGET_SYS_sched_get_priority_max:
2937
          if (arg1 != 0)
2938
            retval = -cb_host_to_target_errno (cb, EINVAL);
2939
          else
2940
            retval = 0;
2941
          break;
2942
 
2943
        case TARGET_SYS_ugetrlimit:
2944
          {
2945
            unsigned int curlim, maxlim;
2946
            if (arg1 != TARGET_RLIMIT_STACK && arg1 != TARGET_RLIMIT_NOFILE)
2947
              {
2948
                retval = -cb_host_to_target_errno (cb, EINVAL);
2949
                break;
2950
              }
2951
 
2952
            /* The kernel says:
2953
               struct rlimit {
2954
                       unsigned long   rlim_cur;
2955
                       unsigned long   rlim_max;
2956
               }; */
2957
            if (arg1 == TARGET_RLIMIT_NOFILE)
2958
              {
2959
                /* Sadly a very low limit.  Better not lie, though.  */
2960
                maxlim = curlim = MAX_CALLBACK_FDS;
2961
              }
2962
            else /* arg1 == TARGET_RLIMIT_STACK */
2963
              {
2964
                maxlim = 0xffffffff;
2965
                curlim = 0x800000;
2966
              }
2967
            sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, curlim);
2968
            sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, maxlim);
2969
            retval = 0;
2970
            break;
2971
          }
2972
 
2973
        case TARGET_SYS_setrlimit:
2974
          if (arg1 != TARGET_RLIMIT_STACK)
2975
            {
2976
              retval = -cb_host_to_target_errno (cb, EINVAL);
2977
              break;
2978
            }
2979
          /* FIXME: Save values for future ugetrlimit calls.  */
2980
          retval = 0;
2981
          break;
2982
 
2983
        /* Provide a very limited subset of the sysctl functions, and
2984
           abort for the rest. */
2985
        case TARGET_SYS__sysctl:
2986
          {
2987
            /* The kernel says:
2988
               struct __sysctl_args {
2989
                int *name;
2990
                int nlen;
2991
                void *oldval;
2992
                size_t *oldlenp;
2993
                void *newval;
2994
                size_t newlen;
2995
                unsigned long __unused[4];
2996
               }; */
2997
            SI name = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1);
2998
            SI name0 = name == 0
2999
              ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name);
3000
            SI name1 = name == 0
3001
              ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name + 4);
3002
            SI nlen
3003
              =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 4);
3004
            SI oldval
3005
              =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 8);
3006
            SI oldlenp
3007
              =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 12);
3008
            SI oldlen = oldlenp == 0
3009
              ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, oldlenp);
3010
            SI newval
3011
              =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 16);
3012
            SI newlen
3013
              = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 20);
3014
 
3015
            if (name0 == TARGET_CTL_KERN && name1 == TARGET_CTL_KERN_VERSION)
3016
              {
3017
                SI to_write = oldlen < (SI) sizeof (TARGET_UTSNAME)
3018
                  ? oldlen : (SI) sizeof (TARGET_UTSNAME);
3019
 
3020
                sim_core_write_unaligned_4 (current_cpu, pc, 0, oldlenp,
3021
                                            sizeof (TARGET_UTSNAME));
3022
 
3023
                if (sim_core_write_buffer (sd, current_cpu, write_map,
3024
                                           TARGET_UTSNAME, oldval,
3025
                                           to_write)
3026
                    != (unsigned int) to_write)
3027
                  retval = -cb_host_to_target_errno (cb, EFAULT);
3028
                else
3029
                  retval = 0;
3030
                break;
3031
              }
3032
 
3033
            retval
3034
              = cris_unknown_syscall (current_cpu, pc,
3035
                                      "Unimplemented _sysctl syscall "
3036
                                      "(0x%lx: [0x%lx, 0x%lx],"
3037
                                      " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3038
                                      (unsigned long) name,
3039
                                      (unsigned long) name0,
3040
                                      (unsigned long) name1,
3041
                                      (unsigned long) nlen,
3042
                                      (unsigned long) oldval,
3043
                                      (unsigned long) oldlenp,
3044
                                      (unsigned long) newval,
3045
                                      (unsigned long) newlen);
3046
            break;
3047
          }
3048
 
3049
        case TARGET_SYS_exit:
3050
          {
3051
            /* Here for all but the last thread.  */
3052
            int i;
3053
            int pid
3054
              = current_cpu->thread_data[threadno].threadid + TARGET_PID;
3055
            int ppid
3056
              = (current_cpu->thread_data[threadno].parent_threadid
3057
                 + TARGET_PID);
3058
            int exitsig = current_cpu->thread_data[threadno].exitsig;
3059
 
3060
            /* Any children are now all orphans.  */
3061
            for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3062
              if (current_cpu->thread_data[i].parent_threadid
3063
                  == current_cpu->thread_data[threadno].threadid)
3064
                /* Make getppid(2) return 1 for them, poor little ones.  */
3065
                current_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1;
3066
 
3067
            /* Free the cpu context data.  When the parent has received
3068
               the exit status, we'll clear the entry too.  */
3069
            free (current_cpu->thread_data[threadno].cpu_context);
3070
            current_cpu->thread_data[threadno].cpu_context = NULL;
3071
            current_cpu->m1threads--;
3072
            if (arg1 != 0)
3073
              {
3074
                sim_io_eprintf (sd, "Thread %d exited with status %d\n",
3075
                                pid, arg1);
3076
                sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
3077
                                 SIM_SIGILL);
3078
              }
3079
 
3080
            /* Still, we may want to support non-zero exit values.  */
3081
            current_cpu->thread_data[threadno].exitval = arg1 << 8;
3082
 
3083
            if (exitsig)
3084
              deliver_signal (current_cpu, exitsig, ppid);
3085
            break;
3086
          }
3087
 
3088
        case TARGET_SYS_clone:
3089
          {
3090
            int nthreads = current_cpu->m1threads + 1;
3091
            void *thread_cpu_data;
3092
            bfd_byte old_sp_buf[4];
3093
            bfd_byte sp_buf[4];
3094
            const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3095
            int i;
3096
 
3097
            /* That's right, the syscall clone arguments are reversed
3098
               compared to sys_clone notes in clone(2) and compared to
3099
               other Linux ports (i.e. it's the same order as in the
3100
               clone(2) libcall).  */
3101
            USI flags = arg2;
3102
            USI newsp = arg1;
3103
 
3104
            if (nthreads == SIM_TARGET_MAX_THREADS)
3105
              {
3106
                retval = -cb_host_to_target_errno (cb, EAGAIN);
3107
                break;
3108
              }
3109
 
3110
            /* FIXME: Implement the low byte.  */
3111
            if ((flags & ~TARGET_CSIGNAL) !=
3112
                (TARGET_CLONE_VM
3113
                 | TARGET_CLONE_FS
3114
                 | TARGET_CLONE_FILES
3115
                 | TARGET_CLONE_SIGHAND)
3116
                || newsp == 0)
3117
              {
3118
                retval
3119
                  = cris_unknown_syscall (current_cpu, pc,
3120
                                          "Unimplemented clone syscall "
3121
                                          "(0x%lx, 0x%lx)\n",
3122
                                          (unsigned long) arg1,
3123
                                          (unsigned long) arg2);
3124
                break;
3125
              }
3126
 
3127
            if (current_cpu->thread_data == NULL)
3128
              make_first_thread (current_cpu);
3129
 
3130
            /* The created thread will get the new SP and a cleared R10.
3131
               Since it's created out of a copy of the old thread and we
3132
               don't have a set-register-function that just take the
3133
               cpu_data as a parameter, we set the childs values first,
3134
               and write back or overwrite them in the parent after the
3135
               copy.  */
3136
            (*CPU_REG_FETCH (current_cpu)) (current_cpu,
3137
                                            H_GR_SP, old_sp_buf, 4);
3138
            bfd_putl32 (newsp, sp_buf);
3139
            (*CPU_REG_STORE (current_cpu)) (current_cpu,
3140
                                            H_GR_SP, sp_buf, 4);
3141
            (*CPU_REG_STORE (current_cpu)) (current_cpu,
3142
                                            H_GR_R10, (bfd_byte *) zeros, 4);
3143
            thread_cpu_data
3144
              = (*current_cpu
3145
                 ->make_thread_cpu_data) (current_cpu,
3146
                                          &current_cpu->cpu_data_placeholder);
3147
            (*CPU_REG_STORE (current_cpu)) (current_cpu,
3148
                                            H_GR_SP, old_sp_buf, 4);
3149
 
3150
            retval = ++current_cpu->max_threadid + TARGET_PID;
3151
 
3152
            /* Find an unused slot.  After a few threads have been created
3153
               and exited, the array is expected to be a bit fragmented.
3154
               We don't reuse the first entry, though, that of the
3155
               original thread.  */
3156
            for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
3157
              if (current_cpu->thread_data[i].cpu_context == NULL
3158
                  /* Don't reuse a zombied entry.  */
3159
                  && current_cpu->thread_data[i].threadid == 0)
3160
                break;
3161
 
3162
            memcpy (&current_cpu->thread_data[i],
3163
                    &current_cpu->thread_data[threadno],
3164
                    sizeof (current_cpu->thread_data[i]));
3165
            current_cpu->thread_data[i].cpu_context = thread_cpu_data;
3166
            current_cpu->thread_data[i].cpu_context_atsignal = NULL;
3167
            current_cpu->thread_data[i].threadid = current_cpu->max_threadid;
3168
            current_cpu->thread_data[i].parent_threadid
3169
              = current_cpu->thread_data[threadno].threadid;
3170
            current_cpu->thread_data[i].pipe_read_fd = 0;
3171
            current_cpu->thread_data[i].pipe_write_fd = 0;
3172
            current_cpu->thread_data[i].at_syscall = 0;
3173
            current_cpu->thread_data[i].sigpending = 0;
3174
            current_cpu->thread_data[i].sigsuspended = 0;
3175
            current_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL;
3176
            current_cpu->m1threads = nthreads;
3177
            break;
3178
          }
3179
 
3180
        /* Better watch these in case they do something necessary.  */
3181
        case TARGET_SYS_socketcall:
3182
          retval = -cb_host_to_target_errno (cb, ENOSYS);
3183
          break;
3184
 
3185
        case TARGET_SYS_set_thread_area:
3186
          /* Do the same error check as Linux.  */
3187
          if (arg1 & 255)
3188
            {
3189
              retval = -cb_host_to_target_errno (cb, EINVAL);
3190
              break;
3191
            }
3192
          (*current_cpu->set_target_thread_data) (current_cpu, arg1);
3193
          retval = 0;
3194
          break;
3195
 
3196
        unimplemented_syscall:
3197
        default:
3198
          retval
3199
            = cris_unknown_syscall (current_cpu, pc,
3200
                                    "Unimplemented syscall: %d "
3201
                                    "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3202
                                    callnum, arg1, arg2, arg3, arg4, arg5,
3203
                                    arg6);
3204
        }
3205
    }
3206
 
3207
  /* Minimal support for fcntl F_GETFL as used in open+fdopen.  */
3208
  if (callnum == TARGET_SYS_open)
3209
    {
3210
      current_cpu->last_open_fd = retval;
3211
      current_cpu->last_open_flags = arg2;
3212
    }
3213
 
3214
  current_cpu->last_syscall = callnum;
3215
 
3216
  /* A system call is a rescheduling point.  For the time being, we don't
3217
     reschedule anywhere else.  */
3218
  if (current_cpu->m1threads != 0
3219
      /* We need to schedule off from an exiting thread that is the
3220
         second-last one.  */
3221
      || (current_cpu->thread_data != NULL
3222
          && current_cpu->thread_data[threadno].cpu_context == NULL))
3223
    {
3224
      bfd_byte retval_buf[4];
3225
 
3226
      current_cpu->thread_data[threadno].last_execution
3227
        = TARGET_TIME_MS (current_cpu);
3228
      bfd_putl32 (retval, retval_buf);
3229
      (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3230
 
3231
      current_cpu->thread_data[threadno].at_syscall = 1;
3232
      reschedule (current_cpu);
3233
 
3234
      (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3235
      retval = bfd_getl32 (retval_buf);
3236
    }
3237
 
3238
  return retval;
3239
}
3240
 
3241
/* Callback from simulator write saying that the pipe at (reader, writer)
3242
   is now non-empty (so the writer should wait until the pipe is empty, at
3243
   least not write to this or any other pipe).  Simplest is to just wait
3244
   until the pipe is empty.  */
3245
 
3246
static void
3247
cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
3248
                    int reader, int writer)
3249
{
3250
  SIM_CPU *cpu = current_cpu_for_cb_callback;
3251
  const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3252
 
3253
  /* It's the current thread: we just have to re-run the current
3254
     syscall instruction (presumably "break 13") and change the syscall
3255
     to the special simulator-wait code.  Oh, and set a marker that
3256
     we're waiting, so we can disambiguate the special call from a
3257
     program error.
3258
 
3259
     This function may be called multiple times between cris_pipe_empty,
3260
     but we must avoid e.g. decreasing PC every time.  Check fd markers
3261
     to tell.  */
3262
  if (cpu->thread_data == NULL)
3263
    {
3264
      sim_io_eprintf (CPU_STATE (cpu),
3265
                      "Terminating simulation due to writing pipe rd:wr %d:%d"
3266
                      " from one single thread\n", reader, writer);
3267
      sim_engine_halt (CPU_STATE (cpu), cpu,
3268
                       NULL, sim_pc_get (cpu), sim_stopped, SIM_SIGILL);
3269
    }
3270
  else if (cpu->thread_data[cpu->threadno].pipe_write_fd == 0)
3271
    {
3272
      cpu->thread_data[cpu->threadno].pipe_write_fd = writer;
3273
      cpu->thread_data[cpu->threadno].pipe_read_fd = reader;
3274
      /* FIXME: We really shouldn't change registers other than R10 in
3275
         syscalls (like R9), here or elsewhere.  */
3276
      (*CPU_REG_STORE (cpu)) (cpu, H_GR_R9, (bfd_byte *) zeros, 4);
3277
      sim_pc_set (cpu, sim_pc_get (cpu) - 2);
3278
    }
3279
}
3280
 
3281
/* Callback from simulator close or read call saying that the pipe at
3282
   (reader, writer) is now empty (so the writer can write again, perhaps
3283
   leave a waiting state).  If there are bytes remaining, they couldn't be
3284
   consumed (perhaps due to the pipe closing).  */
3285
 
3286
static void
3287
cris_pipe_empty (host_callback *cb,
3288
                 int reader,
3289
                 int writer)
3290
{
3291
  int i;
3292
  SIM_CPU *cpu = current_cpu_for_cb_callback;
3293
  SIM_DESC sd = CPU_STATE (current_cpu_for_cb_callback);
3294
  bfd_byte r10_buf[4];
3295
  int remaining
3296
    = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size;
3297
 
3298
  /* We need to find the thread that waits for this pipe.  */
3299
  for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3300
    if (cpu->thread_data[i].cpu_context
3301
        && cpu->thread_data[i].pipe_write_fd == writer)
3302
      {
3303
        int retval;
3304
 
3305
        /* Temporarily switch to this cpu context, so we can change the
3306
           PC by ordinary calls.  */
3307
 
3308
        memcpy (cpu->thread_data[cpu->threadno].cpu_context,
3309
                &cpu->cpu_data_placeholder,
3310
                cpu->thread_cpu_data_size);
3311
        memcpy (&cpu->cpu_data_placeholder,
3312
                cpu->thread_data[i].cpu_context,
3313
                cpu->thread_cpu_data_size);
3314
 
3315
        /* The return value is supposed to contain the number of
3316
           written bytes, which is the number of bytes requested and
3317
           returned at the write call.  You might think the right
3318
           thing is to adjust the return-value to be only the
3319
           *consumed* number of bytes, but it isn't.  We're only
3320
           called if the pipe buffer is fully consumed or it is being
3321
           closed, possibly with remaining bytes.  For the latter
3322
           case, the writer is still supposed to see success for
3323
           PIPE_BUF bytes (a constant which we happen to know and is
3324
           unlikely to change).  The return value may also be a
3325
           negative number; an error value.  This case is covered
3326
           because "remaining" is always >= 0.  */
3327
        (*CPU_REG_FETCH (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3328
        retval = (int) bfd_getl_signed_32 (r10_buf);
3329
        if (retval - remaining > TARGET_PIPE_BUF)
3330
          {
3331
            bfd_putl32 (retval - remaining, r10_buf);
3332
            (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3333
          }
3334
        sim_pc_set (cpu, sim_pc_get (cpu) + 2);
3335
        memcpy (cpu->thread_data[i].cpu_context,
3336
                &cpu->cpu_data_placeholder,
3337
                cpu->thread_cpu_data_size);
3338
        memcpy (&cpu->cpu_data_placeholder,
3339
                cpu->thread_data[cpu->threadno].cpu_context,
3340
                cpu->thread_cpu_data_size);
3341
        cpu->thread_data[i].pipe_read_fd = 0;
3342
        cpu->thread_data[i].pipe_write_fd = 0;
3343
        return;
3344
      }
3345
 
3346
  abort ();
3347
}
3348
 
3349
/* We have a simulator-specific notion of time.  See TARGET_TIME.  */
3350
 
3351
static long
3352
cris_time (host_callback *cb ATTRIBUTE_UNUSED, long *t)
3353
{
3354
  long retval = TARGET_TIME (current_cpu_for_cb_callback);
3355
  if (t)
3356
    *t = retval;
3357
  return retval;
3358
}
3359
 
3360
/* Set target-specific callback data. */
3361
 
3362
void
3363
cris_set_callbacks (host_callback *cb)
3364
{
3365
  /* Yeargh, have to cast away constness to avoid warnings.  */
3366
  cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_map;
3367
  cb->errno_map = (CB_TARGET_DEFS_MAP *) errno_map;
3368
 
3369
  /* The kernel stat64 layout.  If we see a file > 2G, the "long"
3370
     parameter to cb_store_target_endian will make st_size negative.
3371
     Similarly for st_ino.  FIXME: Find a 64-bit type, and use it
3372
     *unsigned*, and/or add syntax for signed-ness.  */
3373
  cb->stat_map = stat_map;
3374
  cb->open_map = (CB_TARGET_DEFS_MAP *) open_map;
3375
  cb->pipe_nonempty = cris_pipe_nonempty;
3376
  cb->pipe_empty = cris_pipe_empty;
3377
  cb->time = cris_time;
3378
}
3379
 
3380
/* Process an address exception.  */
3381
 
3382
void
3383
cris_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
3384
                  unsigned int map, int nr_bytes, address_word addr,
3385
                  transfer_type transfer, sim_core_signals sig)
3386
{
3387
  sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
3388
                   transfer, sig);
3389
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.