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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [cris/] [traps.c] - Blame information for rev 26

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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