sim: ppc: fix some Wunused-function warnings
[binutils-gdb.git] / sim / bfin / interp.c
1 /* Simulator for Analog Devices Blackfin processors.
2
3 Copyright (C) 2005-2021 Free Software Foundation, Inc.
4 Contributed by Analog Devices, Inc.
5
6 This file is part of simulators.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* This must come before any other includes. */
22 #include "defs.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <signal.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <sys/time.h>
32
33 #include "sim/callback.h"
34 #include "gdb/signals.h"
35 #include "sim-main.h"
36 #include "sim-syscall.h"
37 #include "sim-hw.h"
38
39 #include "targ-vals.h"
40
41 /* The numbers here do not matter. They just need to be unique. They also
42 need not be static across releases -- they're used internally only. The
43 mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
44 #define CB_SYS_ioctl 201
45 #define CB_SYS_mmap2 202
46 #define CB_SYS_munmap 203
47 #define CB_SYS_dup2 204
48 #define CB_SYS_getuid 205
49 #define CB_SYS_getuid32 206
50 #define CB_SYS_getgid 207
51 #define CB_SYS_getgid32 208
52 #define CB_SYS_setuid 209
53 #define CB_SYS_setuid32 210
54 #define CB_SYS_setgid 211
55 #define CB_SYS_setgid32 212
56 #define CB_SYS_pread 213
57 #define CB_SYS__llseek 214
58 #define CB_SYS_getcwd 215
59 #define CB_SYS_stat64 216
60 #define CB_SYS_lstat64 217
61 #define CB_SYS_fstat64 218
62 #define CB_SYS_ftruncate64 219
63 #define CB_SYS_gettimeofday 220
64 #define CB_SYS_access 221
65 #include "linux-targ-map.h"
66 #include "linux-fixed-code.h"
67
68 #include "elf/common.h"
69 #include "elf/external.h"
70 #include "elf/internal.h"
71 #include "elf/bfin.h"
72 #include "elf-bfd.h"
73
74 #include "dv-bfin_cec.h"
75 #include "dv-bfin_mmu.h"
76
77 #ifndef HAVE_GETUID
78 # define getuid() 0
79 #endif
80 #ifndef HAVE_GETGID
81 # define getgid() 0
82 #endif
83 #ifndef HAVE_GETEUID
84 # define geteuid() 0
85 #endif
86 #ifndef HAVE_GETEGID
87 # define getegid() 0
88 #endif
89 #ifndef HAVE_SETUID
90 # define setuid(uid) -1
91 #endif
92 #ifndef HAVE_SETGID
93 # define setgid(gid) -1
94 #endif
95
96 static const char cb_linux_stat_map_32[] =
97 /* Linux kernel 32bit layout: */
98 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
99 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
100 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
101 /* uClibc public ABI 32bit layout:
102 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
103 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
104 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
105 "space,4"; */
106 static const char cb_linux_stat_map_64[] =
107 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
108 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
109 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
110 static const char cb_libgloss_stat_map_32[] =
111 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
112 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
113 "space,4:st_blksize,4:st_blocks,4:space,8";
114 static const char *stat_map_32, *stat_map_64;
115
116 /* Simulate a monitor trap, put the result into r0 and errno into r1
117 return offset by which to adjust pc. */
118
119 void
120 bfin_syscall (SIM_CPU *cpu)
121 {
122 SIM_DESC sd = CPU_STATE (cpu);
123 char * const *argv = (void *)STATE_PROG_ARGV (sd);
124 host_callback *cb = STATE_CALLBACK (sd);
125 bu32 args[6];
126 CB_SYSCALL sc;
127 char *p;
128 char _tbuf[1024 * 3], *tbuf = _tbuf, tstr[1024];
129 int fmt_ret_hex = 0;
130
131 CB_SYSCALL_INIT (&sc);
132
133 if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
134 {
135 /* Linux syscall. */
136 sc.func = PREG (0);
137 sc.arg1 = args[0] = DREG (0);
138 sc.arg2 = args[1] = DREG (1);
139 sc.arg3 = args[2] = DREG (2);
140 sc.arg4 = args[3] = DREG (3);
141 /*sc.arg5 =*/ args[4] = DREG (4);
142 /*sc.arg6 =*/ args[5] = DREG (5);
143 }
144 else
145 {
146 /* libgloss syscall. */
147 sc.func = PREG (0);
148 sc.arg1 = args[0] = GET_LONG (DREG (0));
149 sc.arg2 = args[1] = GET_LONG (DREG (0) + 4);
150 sc.arg3 = args[2] = GET_LONG (DREG (0) + 8);
151 sc.arg4 = args[3] = GET_LONG (DREG (0) + 12);
152 /*sc.arg5 =*/ args[4] = GET_LONG (DREG (0) + 16);
153 /*sc.arg6 =*/ args[5] = GET_LONG (DREG (0) + 20);
154 }
155 sc.p1 = (PTR) sd;
156 sc.p2 = (PTR) cpu;
157 sc.read_mem = sim_syscall_read_mem;
158 sc.write_mem = sim_syscall_write_mem;
159
160 /* Common cb_syscall() handles most functions. */
161 switch (cb_target_to_host_syscall (cb, sc.func))
162 {
163 case CB_SYS_exit:
164 tbuf += sprintf (tbuf, "exit(%i)", args[0]);
165 sim_engine_halt (sd, cpu, NULL, PCREG, sim_exited, sc.arg1);
166
167 #ifdef CB_SYS_argc
168 case CB_SYS_argc:
169 tbuf += sprintf (tbuf, "argc()");
170 sc.result = countargv ((char **)argv);
171 break;
172 case CB_SYS_argnlen:
173 {
174 tbuf += sprintf (tbuf, "argnlen(%u)", args[0]);
175 if (sc.arg1 < countargv ((char **)argv))
176 sc.result = strlen (argv[sc.arg1]);
177 else
178 sc.result = -1;
179 }
180 break;
181 case CB_SYS_argn:
182 {
183 tbuf += sprintf (tbuf, "argn(%u)", args[0]);
184 if (sc.arg1 < countargv ((char **)argv))
185 {
186 const char *argn = argv[sc.arg1];
187 int len = strlen (argn);
188 int written = sc.write_mem (cb, &sc, sc.arg2, argn, len + 1);
189 if (written == len + 1)
190 sc.result = sc.arg2;
191 else
192 sc.result = -1;
193 }
194 else
195 sc.result = -1;
196 }
197 break;
198 #endif
199
200 case CB_SYS_gettimeofday:
201 {
202 struct timeval _tv, *tv = &_tv;
203 struct timezone _tz, *tz = &_tz;
204
205 tbuf += sprintf (tbuf, "gettimeofday(%#x, %#x)", args[0], args[1]);
206
207 if (sc.arg1 == 0)
208 tv = NULL;
209 if (sc.arg2 == 0)
210 tz = NULL;
211 sc.result = gettimeofday (tv, tz);
212
213 if (sc.result == 0)
214 {
215 bu32 t;
216
217 if (tv)
218 {
219 t = tv->tv_sec;
220 sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
221 t = tv->tv_usec;
222 sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
223 }
224
225 if (sc.arg2)
226 {
227 t = tz->tz_minuteswest;
228 sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
229 t = tz->tz_dsttime;
230 sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
231 }
232 }
233 else
234 goto sys_finish;
235 }
236 break;
237
238 case CB_SYS_ioctl:
239 /* XXX: hack just enough to get basic stdio w/uClibc ... */
240 tbuf += sprintf (tbuf, "ioctl(%i, %#x, %u)", args[0], args[1], args[2]);
241 if (sc.arg2 == 0x5401)
242 {
243 sc.result = !isatty (sc.arg1);
244 sc.errcode = 0;
245 }
246 else
247 {
248 sc.result = -1;
249 sc.errcode = TARGET_EINVAL;
250 }
251 break;
252
253 case CB_SYS_mmap2:
254 {
255 static bu32 heap = BFIN_DEFAULT_MEM_SIZE / 2;
256
257 fmt_ret_hex = 1;
258 tbuf += sprintf (tbuf, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
259 args[0], args[1], args[2], args[3], args[4], args[5]);
260
261 sc.errcode = 0;
262
263 if (sc.arg4 & 0x20 /*MAP_ANONYMOUS*/)
264 /* XXX: We don't handle zeroing, but default is all zeros. */;
265 else if (args[4] >= MAX_CALLBACK_FDS)
266 sc.errcode = TARGET_ENOSYS;
267 else
268 {
269 #ifdef HAVE_PREAD
270 char *data = xmalloc (sc.arg2);
271
272 /* XXX: Should add a cb->pread. */
273 if (pread (cb->fdmap[args[4]], data, sc.arg2, args[5] << 12) == sc.arg2)
274 sc.write_mem (cb, &sc, heap, data, sc.arg2);
275 else
276 sc.errcode = TARGET_EINVAL;
277
278 free (data);
279 #else
280 sc.errcode = TARGET_ENOSYS;
281 #endif
282 }
283
284 if (sc.errcode)
285 {
286 sc.result = -1;
287 break;
288 }
289
290 sc.result = heap;
291 heap += sc.arg2;
292 /* Keep it page aligned. */
293 heap = align_up (heap, 4096);
294
295 break;
296 }
297
298 case CB_SYS_munmap:
299 /* XXX: meh, just lie for mmap(). */
300 tbuf += sprintf (tbuf, "munmap(%#x, %u)", args[0], args[1]);
301 sc.result = 0;
302 break;
303
304 case CB_SYS_dup2:
305 tbuf += sprintf (tbuf, "dup2(%i, %i)", args[0], args[1]);
306 if (sc.arg1 >= MAX_CALLBACK_FDS || sc.arg2 >= MAX_CALLBACK_FDS)
307 {
308 sc.result = -1;
309 sc.errcode = TARGET_EINVAL;
310 }
311 else
312 {
313 sc.result = dup2 (cb->fdmap[sc.arg1], cb->fdmap[sc.arg2]);
314 goto sys_finish;
315 }
316 break;
317
318 case CB_SYS__llseek:
319 tbuf += sprintf (tbuf, "llseek(%i, %u, %u, %#x, %u)",
320 args[0], args[1], args[2], args[3], args[4]);
321 sc.func = TARGET_LINUX_SYS_lseek;
322 if (sc.arg2)
323 {
324 sc.result = -1;
325 sc.errcode = TARGET_EINVAL;
326 }
327 else
328 {
329 sc.arg2 = sc.arg3;
330 sc.arg3 = args[4];
331 cb_syscall (cb, &sc);
332 if (sc.result != -1)
333 {
334 bu32 z = 0;
335 sc.write_mem (cb, &sc, args[3], (void *)&sc.result, 4);
336 sc.write_mem (cb, &sc, args[3] + 4, (void *)&z, 4);
337 }
338 }
339 break;
340
341 /* XXX: Should add a cb->pread. */
342 case CB_SYS_pread:
343 tbuf += sprintf (tbuf, "pread(%i, %#x, %u, %i)",
344 args[0], args[1], args[2], args[3]);
345 if (sc.arg1 >= MAX_CALLBACK_FDS)
346 {
347 sc.result = -1;
348 sc.errcode = TARGET_EINVAL;
349 }
350 else
351 {
352 long old_pos, read_result, read_errcode;
353
354 /* Get current filepos. */
355 sc.func = TARGET_LINUX_SYS_lseek;
356 sc.arg2 = 0;
357 sc.arg3 = SEEK_CUR;
358 cb_syscall (cb, &sc);
359 if (sc.result == -1)
360 break;
361 old_pos = sc.result;
362
363 /* Move to the new pos. */
364 sc.func = TARGET_LINUX_SYS_lseek;
365 sc.arg2 = args[3];
366 sc.arg3 = SEEK_SET;
367 cb_syscall (cb, &sc);
368 if (sc.result == -1)
369 break;
370
371 /* Read the data. */
372 sc.func = TARGET_LINUX_SYS_read;
373 sc.arg2 = args[1];
374 sc.arg3 = args[2];
375 cb_syscall (cb, &sc);
376 read_result = sc.result;
377 read_errcode = sc.errcode;
378
379 /* Move back to the old pos. */
380 sc.func = TARGET_LINUX_SYS_lseek;
381 sc.arg2 = old_pos;
382 sc.arg3 = SEEK_SET;
383 cb_syscall (cb, &sc);
384
385 sc.result = read_result;
386 sc.errcode = read_errcode;
387 }
388 break;
389
390 case CB_SYS_getcwd:
391 tbuf += sprintf (tbuf, "getcwd(%#x, %u)", args[0], args[1]);
392
393 p = alloca (sc.arg2);
394 if (getcwd (p, sc.arg2) == NULL)
395 {
396 sc.result = -1;
397 sc.errcode = TARGET_EINVAL;
398 }
399 else
400 {
401 sc.write_mem (cb, &sc, sc.arg1, p, sc.arg2);
402 sc.result = sc.arg1;
403 }
404 break;
405
406 case CB_SYS_stat64:
407 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
408 strcpy (tstr, "???");
409 tbuf += sprintf (tbuf, "stat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
410 cb->stat_map = stat_map_64;
411 sc.func = TARGET_LINUX_SYS_stat;
412 cb_syscall (cb, &sc);
413 cb->stat_map = stat_map_32;
414 break;
415 case CB_SYS_lstat64:
416 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
417 strcpy (tstr, "???");
418 tbuf += sprintf (tbuf, "lstat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
419 cb->stat_map = stat_map_64;
420 sc.func = TARGET_LINUX_SYS_lstat;
421 cb_syscall (cb, &sc);
422 cb->stat_map = stat_map_32;
423 break;
424 case CB_SYS_fstat64:
425 tbuf += sprintf (tbuf, "fstat64(%#x, %u)", args[0], args[1]);
426 cb->stat_map = stat_map_64;
427 sc.func = TARGET_LINUX_SYS_fstat;
428 cb_syscall (cb, &sc);
429 cb->stat_map = stat_map_32;
430 break;
431
432 case CB_SYS_ftruncate64:
433 tbuf += sprintf (tbuf, "ftruncate64(%u, %u)", args[0], args[1]);
434 sc.func = TARGET_LINUX_SYS_ftruncate;
435 cb_syscall (cb, &sc);
436 break;
437
438 case CB_SYS_getuid:
439 case CB_SYS_getuid32:
440 tbuf += sprintf (tbuf, "getuid()");
441 sc.result = getuid ();
442 goto sys_finish;
443 case CB_SYS_getgid:
444 case CB_SYS_getgid32:
445 tbuf += sprintf (tbuf, "getgid()");
446 sc.result = getgid ();
447 goto sys_finish;
448 case CB_SYS_setuid:
449 sc.arg1 &= 0xffff;
450 case CB_SYS_setuid32:
451 tbuf += sprintf (tbuf, "setuid(%u)", args[0]);
452 sc.result = setuid (sc.arg1);
453 goto sys_finish;
454 case CB_SYS_setgid:
455 sc.arg1 &= 0xffff;
456 case CB_SYS_setgid32:
457 tbuf += sprintf (tbuf, "setgid(%u)", args[0]);
458 sc.result = setgid (sc.arg1);
459 goto sys_finish;
460
461 case CB_SYS_kill:
462 tbuf += sprintf (tbuf, "kill(%u, %i)", args[0], args[1]);
463 /* Only let the app kill itself. */
464 if (sc.arg1 != getpid ())
465 {
466 sc.result = -1;
467 sc.errcode = TARGET_EPERM;
468 }
469 else
470 {
471 #ifdef HAVE_KILL
472 sc.result = kill (sc.arg1, sc.arg2);
473 goto sys_finish;
474 #else
475 sc.result = -1;
476 sc.errcode = TARGET_ENOSYS;
477 #endif
478 }
479 break;
480
481 case CB_SYS_open:
482 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
483 strcpy (tstr, "???");
484 tbuf += sprintf (tbuf, "open(%#x:\"%s\", %#x, %o)",
485 args[0], tstr, args[1], args[2]);
486 goto case_default;
487 case CB_SYS_close:
488 tbuf += sprintf (tbuf, "close(%i)", args[0]);
489 goto case_default;
490 case CB_SYS_read:
491 tbuf += sprintf (tbuf, "read(%i, %#x, %u)", args[0], args[1], args[2]);
492 goto case_default;
493 case CB_SYS_write:
494 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
495 strcpy (tstr, "???");
496 tbuf += sprintf (tbuf, "write(%i, %#x:\"%s\", %u)",
497 args[0], args[1], tstr, args[2]);
498 goto case_default;
499 case CB_SYS_lseek:
500 tbuf += sprintf (tbuf, "lseek(%i, %i, %i)", args[0], args[1], args[2]);
501 goto case_default;
502 case CB_SYS_unlink:
503 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
504 strcpy (tstr, "???");
505 tbuf += sprintf (tbuf, "unlink(%#x:\"%s\")", args[0], tstr);
506 goto case_default;
507 case CB_SYS_truncate:
508 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
509 strcpy (tstr, "???");
510 tbuf += sprintf (tbuf, "truncate(%#x:\"%s\", %i)", args[0], tstr, args[1]);
511 goto case_default;
512 case CB_SYS_ftruncate:
513 tbuf += sprintf (tbuf, "ftruncate(%i, %i)", args[0], args[1]);
514 goto case_default;
515 case CB_SYS_rename:
516 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
517 strcpy (tstr, "???");
518 tbuf += sprintf (tbuf, "rename(%#x:\"%s\", ", args[0], tstr);
519 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
520 strcpy (tstr, "???");
521 tbuf += sprintf (tbuf, "%#x:\"%s\")", args[1], tstr);
522 goto case_default;
523 case CB_SYS_stat:
524 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
525 strcpy (tstr, "???");
526 tbuf += sprintf (tbuf, "stat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
527 goto case_default;
528 case CB_SYS_fstat:
529 tbuf += sprintf (tbuf, "fstat(%i, %#x)", args[0], args[1]);
530 goto case_default;
531 case CB_SYS_lstat:
532 if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
533 strcpy (tstr, "???");
534 tbuf += sprintf (tbuf, "lstat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
535 goto case_default;
536 case CB_SYS_pipe:
537 tbuf += sprintf (tbuf, "pipe(%#x, %#x)", args[0], args[1]);
538 goto case_default;
539
540 default:
541 tbuf += sprintf (tbuf, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc.func,
542 args[0], args[1], args[2], args[3], args[4], args[5]);
543 case_default:
544 cb_syscall (cb, &sc);
545 break;
546
547 sys_finish:
548 if (sc.result == -1)
549 {
550 cb->last_errno = errno;
551 sc.errcode = cb->get_errno (cb);
552 }
553 }
554
555 TRACE_EVENTS (cpu, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
556 sc.func, args[0], args[1], args[2], args[3], args[4], args[5],
557 sc.result, sc.errcode);
558
559 tbuf += sprintf (tbuf, " = ");
560 if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
561 {
562 if (sc.result == -1)
563 {
564 tbuf += sprintf (tbuf, "-1 (error = %i)", sc.errcode);
565 if (sc.errcode == cb_host_to_target_errno (cb, ENOSYS))
566 {
567 sim_io_eprintf (sd, "bfin-sim: %#x: unimplemented syscall %i\n",
568 PCREG, sc.func);
569 }
570 SET_DREG (0, -sc.errcode);
571 }
572 else
573 {
574 if (fmt_ret_hex)
575 tbuf += sprintf (tbuf, "%#lx", sc.result);
576 else
577 tbuf += sprintf (tbuf, "%lu", sc.result);
578 SET_DREG (0, sc.result);
579 }
580 }
581 else
582 {
583 tbuf += sprintf (tbuf, "%lu (error = %i)", sc.result, sc.errcode);
584 SET_DREG (0, sc.result);
585 SET_DREG (1, sc.result2);
586 SET_DREG (2, sc.errcode);
587 }
588
589 TRACE_SYSCALL (cpu, "%s", _tbuf);
590 }
591
592 /* Execute a single instruction. */
593
594 static sim_cia
595 step_once (SIM_CPU *cpu)
596 {
597 SIM_DESC sd = CPU_STATE (cpu);
598 bu32 insn_len, oldpc = PCREG;
599 int i;
600 bool ssstep;
601
602 if (TRACE_ANY_P (cpu))
603 trace_prefix (sd, cpu, NULL_CIA, oldpc, TRACE_LINENUM_P (cpu),
604 NULL, 0, " "); /* Use a space for gcc warnings. */
605
606 TRACE_DISASM (cpu, oldpc);
607
608 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
609 has already had the SSSTEP bit enabled. */
610 ssstep = false;
611 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT
612 && (SYSCFGREG & SYSCFG_SSSTEP))
613 {
614 int ivg = cec_get_ivg (cpu);
615 if (ivg == -1 || ivg > 3)
616 ssstep = true;
617 }
618
619 #if 0
620 /* XXX: Is this what happens on the hardware ? */
621 if (cec_get_ivg (cpu) == EVT_EMU)
622 cec_return (cpu, EVT_EMU);
623 #endif
624
625 BFIN_CPU_STATE.did_jump = false;
626
627 insn_len = interp_insn_bfin (cpu, oldpc);
628
629 /* If we executed this insn successfully, then we always decrement
630 the loop counter. We don't want to update the PC though if the
631 last insn happened to be a change in code flow (jump/etc...). */
632 if (!BFIN_CPU_STATE.did_jump)
633 SET_PCREG (hwloop_get_next_pc (cpu, oldpc, insn_len));
634 for (i = 1; i >= 0; --i)
635 if (LCREG (i) && oldpc == LBREG (i))
636 {
637 SET_LCREG (i, LCREG (i) - 1);
638 if (LCREG (i))
639 break;
640 }
641
642 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu));
643
644 /* Handle hardware single stepping only if we're still lower than EVT3.
645 XXX: May not be entirely correct wrt EXCPT insns. */
646 if (ssstep)
647 {
648 int ivg = cec_get_ivg (cpu);
649 if (ivg == -1 || ivg > 3)
650 {
651 INSN_LEN = 0;
652 cec_exception (cpu, VEC_STEP);
653 }
654 }
655
656 return oldpc;
657 }
658
659 void
660 sim_engine_run (SIM_DESC sd,
661 int next_cpu_nr, /* ignore */
662 int nr_cpus, /* ignore */
663 int siggnal) /* ignore */
664 {
665 bu32 ticks;
666 SIM_CPU *cpu;
667
668 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
669
670 cpu = STATE_CPU (sd, 0);
671
672 while (1)
673 {
674 step_once (cpu);
675 /* Process any events -- can't use tickn because it may
676 advance right over the next event. */
677 for (ticks = 0; ticks < CYCLE_DELAY; ++ticks)
678 if (sim_events_tick (sd))
679 sim_events_process (sd);
680 }
681 }
682
683 /* Cover function of sim_state_free to free the cpu buffers as well. */
684
685 static void
686 free_state (SIM_DESC sd)
687 {
688 if (STATE_MODULES (sd) != NULL)
689 sim_module_uninstall (sd);
690 sim_cpu_free_all (sd);
691 sim_state_free (sd);
692 }
693
694 /* Create an instance of the simulator. */
695
696 static void
697 bfin_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
698 {
699 memset (&cpu->state, 0, sizeof (cpu->state));
700
701 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) = 0;
702
703 bfin_model_cpu_init (sd, cpu);
704
705 /* Set default stack to top of scratch pad. */
706 SET_SPREG (BFIN_DEFAULT_MEM_SIZE);
707 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE);
708 SET_USPREG (BFIN_DEFAULT_MEM_SIZE);
709
710 /* This is what the hardware likes. */
711 SET_SYSCFGREG (0x30);
712 }
713
714 SIM_DESC
715 sim_open (SIM_OPEN_KIND kind, host_callback *callback,
716 struct bfd *abfd, char * const *argv)
717 {
718 char c;
719 int i;
720 SIM_DESC sd = sim_state_alloc_extra (kind, callback,
721 sizeof (struct bfin_board_data));
722
723 /* The cpu data is kept in a separately allocated chunk of memory. */
724 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
725 {
726 free_state (sd);
727 return 0;
728 }
729
730 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
731 {
732 free_state (sd);
733 return 0;
734 }
735
736 /* XXX: Default to the Virtual environment. */
737 if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
738 STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
739
740 /* The parser will print an error message for us, so we silently return. */
741 if (sim_parse_args (sd, argv) != SIM_RC_OK)
742 {
743 free_state (sd);
744 return 0;
745 }
746
747 /* Allocate external memory if none specified by user.
748 Use address 4 here in case the user wanted address 0 unmapped. */
749 if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
750 {
751 bu16 emuexcpt = 0x25;
752 sim_do_commandf (sd, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE);
753 sim_write (sd, 0, (void *)&emuexcpt, 2);
754 }
755
756 /* Check for/establish the a reference program image. */
757 if (sim_analyze_program (sd,
758 (STATE_PROG_ARGV (sd) != NULL
759 ? *STATE_PROG_ARGV (sd)
760 : NULL), abfd) != SIM_RC_OK)
761 {
762 free_state (sd);
763 return 0;
764 }
765
766 /* Establish any remaining configuration options. */
767 if (sim_config (sd) != SIM_RC_OK)
768 {
769 free_state (sd);
770 return 0;
771 }
772
773 if (sim_post_argv_init (sd) != SIM_RC_OK)
774 {
775 free_state (sd);
776 return 0;
777 }
778
779 /* CPU specific initialization. */
780 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
781 {
782 SIM_CPU *cpu = STATE_CPU (sd, i);
783 bfin_initialize_cpu (sd, cpu);
784 }
785
786 return sd;
787 }
788
789 /* Some utils don't like having a NULL environ. */
790 static char * const simple_env[] = { "HOME=/", "PATH=/bin", NULL };
791
792 static bu32 fdpic_load_offset;
793
794 static bool
795 bfin_fdpic_load (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, bu32 *sp,
796 bu32 *elf_addrs, char **ldso_path)
797 {
798 bool ret;
799 int i;
800
801 Elf_Internal_Ehdr *iehdr;
802 Elf32_External_Ehdr ehdr;
803 Elf_Internal_Phdr *phdrs;
804 unsigned char *data;
805 long phdr_size;
806 int phdrc;
807 bu32 nsegs;
808
809 bu32 max_load_addr;
810
811 unsigned char null[4] = { 0, 0, 0, 0 };
812
813 ret = false;
814 *ldso_path = NULL;
815
816 /* See if this an FDPIC ELF. */
817 phdrs = NULL;
818 if (!abfd)
819 goto skip_fdpic_init;
820 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
821 goto skip_fdpic_init;
822 if (bfd_bread (&ehdr, sizeof (ehdr), abfd) != sizeof (ehdr))
823 goto skip_fdpic_init;
824 iehdr = elf_elfheader (abfd);
825 if (!(iehdr->e_flags & EF_BFIN_FDPIC))
826 goto skip_fdpic_init;
827
828 if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
829 sim_io_printf (sd, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
830 bfd_get_filename (abfd), fdpic_load_offset, elf_addrs[0]);
831
832 /* Grab the Program Headers to set up the loadsegs on the stack. */
833 phdr_size = bfd_get_elf_phdr_upper_bound (abfd);
834 if (phdr_size == -1)
835 goto skip_fdpic_init;
836 phdrs = xmalloc (phdr_size);
837 phdrc = bfd_get_elf_phdrs (abfd, phdrs);
838 if (phdrc == -1)
839 goto skip_fdpic_init;
840
841 /* Push the Ehdr onto the stack. */
842 *sp -= sizeof (ehdr);
843 elf_addrs[3] = *sp;
844 sim_write (sd, *sp, (void *)&ehdr, sizeof (ehdr));
845 if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
846 sim_io_printf (sd, " Elf_Ehdr: %#x\n", *sp);
847
848 /* Since we're relocating things ourselves, we need to relocate
849 the start address as well. */
850 elf_addrs[0] = bfd_get_start_address (abfd) + fdpic_load_offset;
851
852 /* And the Exec's Phdrs onto the stack. */
853 if (STATE_PROG_BFD (sd) == abfd)
854 {
855 elf_addrs[4] = elf_addrs[0];
856
857 phdr_size = iehdr->e_phentsize * iehdr->e_phnum;
858 if (bfd_seek (abfd, iehdr->e_phoff, SEEK_SET) != 0)
859 goto skip_fdpic_init;
860 data = xmalloc (phdr_size);
861 if (bfd_bread (data, phdr_size, abfd) != phdr_size)
862 goto skip_fdpic_init;
863 *sp -= phdr_size;
864 elf_addrs[1] = *sp;
865 elf_addrs[2] = phdrc;
866 sim_write (sd, *sp, data, phdr_size);
867 free (data);
868 if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
869 sim_io_printf (sd, " Elf_Phdrs: %#x\n", *sp);
870 }
871
872 /* Now push all the loadsegs. */
873 nsegs = 0;
874 max_load_addr = 0;
875 for (i = phdrc; i >= 0; --i)
876 if (phdrs[i].p_type == PT_LOAD)
877 {
878 Elf_Internal_Phdr *p = &phdrs[i];
879 bu32 paddr, vaddr, memsz, filesz;
880
881 paddr = p->p_paddr + fdpic_load_offset;
882 vaddr = p->p_vaddr;
883 memsz = p->p_memsz;
884 filesz = p->p_filesz;
885
886 if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
887 sim_io_printf (sd, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
888 i, vaddr, paddr, filesz, memsz);
889
890 data = xmalloc (memsz);
891 if (memsz != filesz)
892 memset (data + filesz, 0, memsz - filesz);
893
894 if (bfd_seek (abfd, p->p_offset, SEEK_SET) == 0
895 && bfd_bread (data, filesz, abfd) == filesz)
896 sim_write (sd, paddr, data, memsz);
897
898 free (data);
899
900 max_load_addr = max (paddr + memsz, max_load_addr);
901
902 *sp -= 12;
903 sim_write (sd, *sp+0, (void *)&paddr, 4); /* loadseg.addr */
904 sim_write (sd, *sp+4, (void *)&vaddr, 4); /* loadseg.p_vaddr */
905 sim_write (sd, *sp+8, (void *)&memsz, 4); /* loadseg.p_memsz */
906 ++nsegs;
907 }
908 else if (phdrs[i].p_type == PT_DYNAMIC)
909 {
910 elf_addrs[5] = phdrs[i].p_paddr + fdpic_load_offset;
911 if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
912 sim_io_printf (sd, " PT_DYNAMIC: %#x\n", elf_addrs[5]);
913 }
914 else if (phdrs[i].p_type == PT_INTERP)
915 {
916 uint32_t off = phdrs[i].p_offset;
917 uint32_t len = phdrs[i].p_filesz;
918
919 *ldso_path = xmalloc (len);
920 if (bfd_seek (abfd, off, SEEK_SET) != 0
921 || bfd_bread (*ldso_path, len, abfd) != len)
922 {
923 free (*ldso_path);
924 *ldso_path = NULL;
925 }
926 else if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
927 sim_io_printf (sd, " PT_INTERP: %s\n", *ldso_path);
928 }
929
930 /* Update the load offset with a few extra pages. */
931 fdpic_load_offset = align_up (max (max_load_addr, fdpic_load_offset),
932 0x10000);
933 fdpic_load_offset += 0x10000;
934
935 /* Push the summary loadmap info onto the stack last. */
936 *sp -= 4;
937 sim_write (sd, *sp+0, null, 2); /* loadmap.version */
938 sim_write (sd, *sp+2, (void *)&nsegs, 2); /* loadmap.nsegs */
939
940 ret = true;
941 skip_fdpic_init:
942 free (phdrs);
943
944 return ret;
945 }
946
947 static void
948 bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
949 char * const *argv, char * const *env)
950 {
951 /* XXX: Missing host -> target endian ... */
952 /* Linux starts the user app with the stack:
953 argc
954 argv[0] -- pointers to the actual strings
955 argv[1..N]
956 NULL
957 env[0]
958 env[1..N]
959 NULL
960 auxvt[0].type -- ELF Auxiliary Vector Table
961 auxvt[0].value
962 auxvt[1..N]
963 AT_NULL
964 0
965 argv[0..N][0..M] -- actual argv/env strings
966 env[0..N][0..M]
967 FDPIC loadmaps -- for FDPIC apps
968 So set things up the same way. */
969 int i, argc, envc;
970 bu32 argv_flat, env_flat;
971
972 bu32 sp, sp_flat;
973
974 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
975 bu32 elf_addrs[6];
976 bu32 auxvt;
977 bu32 exec_loadmap, ldso_loadmap;
978 char *ldso_path;
979
980 unsigned char null[4] = { 0, 0, 0, 0 };
981
982 host_callback *cb = STATE_CALLBACK (sd);
983
984 elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd);
985 elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0;
986
987 /* Keep the load addresses consistent between runs. Also make sure we make
988 space for the fixed code region (part of the Blackfin Linux ABI). */
989 fdpic_load_offset = 0x1000;
990
991 /* First try to load this as an FDPIC executable. */
992 sp = SPREG;
993 if (!bfin_fdpic_load (sd, cpu, STATE_PROG_BFD (sd), &sp, elf_addrs, &ldso_path))
994 goto skip_fdpic_init;
995 exec_loadmap = sp;
996
997 /* If that worked, then load the fixed code region. We only do this for
998 FDPIC ELFs atm because they are PIEs and let us relocate them without
999 manual fixups. FLAT files however require location processing which
1000 we do not do ourselves, and they link with a VMA of 0. */
1001 sim_write (sd, 0x400, bfin_linux_fixed_code, sizeof (bfin_linux_fixed_code));
1002
1003 /* If the FDPIC needs an interpreter, then load it up too. */
1004 if (ldso_path)
1005 {
1006 const char *ldso_full_path = concat (simulator_sysroot, ldso_path, NULL);
1007 struct bfd *ldso_bfd;
1008
1009 ldso_bfd = bfd_openr (ldso_full_path, STATE_TARGET (sd));
1010 if (!ldso_bfd)
1011 {
1012 sim_io_eprintf (sd, "bfin-sim: bfd open failed: %s\n", ldso_full_path);
1013 goto static_fdpic;
1014 }
1015 if (!bfd_check_format (ldso_bfd, bfd_object))
1016 sim_io_eprintf (sd, "bfin-sim: bfd format not valid: %s\n", ldso_full_path);
1017 bfd_set_arch_info (ldso_bfd, STATE_ARCHITECTURE (sd));
1018
1019 if (!bfin_fdpic_load (sd, cpu, ldso_bfd, &sp, elf_addrs, &ldso_path))
1020 sim_io_eprintf (sd, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path);
1021 if (ldso_path)
1022 sim_io_eprintf (sd, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1023 ldso_full_path, ldso_path);
1024
1025 ldso_loadmap = sp;
1026 }
1027 else
1028 static_fdpic:
1029 ldso_loadmap = 0;
1030
1031 /* Finally setup the registers required by the FDPIC ABI. */
1032 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1033 SET_PREG (0, exec_loadmap); /* Exec loadmap addr. */
1034 SET_PREG (1, ldso_loadmap); /* Interp loadmap addr. */
1035 SET_PREG (2, elf_addrs[5]); /* PT_DYNAMIC map addr. */
1036
1037 auxvt = 1;
1038 SET_SPREG (sp);
1039 skip_fdpic_init:
1040 sim_pc_set (cpu, elf_addrs[0]);
1041
1042 /* Figure out how much storage the argv/env strings need. */
1043 argc = countargv ((char **)argv);
1044 if (argc == -1)
1045 argc = 0;
1046 argv_flat = argc; /* NUL bytes */
1047 for (i = 0; i < argc; ++i)
1048 argv_flat += strlen (argv[i]);
1049
1050 if (!env)
1051 env = simple_env;
1052 envc = countargv ((char **)env);
1053 env_flat = envc; /* NUL bytes */
1054 for (i = 0; i < envc; ++i)
1055 env_flat += strlen (env[i]);
1056
1057 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1058 sp_flat = sp = align_up (SPREG - argv_flat - env_flat - 4, 4);
1059 if (auxvt)
1060 {
1061 # define AT_PUSH(at, val) \
1062 auxvt_size += 8; \
1063 sp -= 4; \
1064 auxvt = (val); \
1065 sim_write (sd, sp, (void *)&auxvt, 4); \
1066 sp -= 4; \
1067 auxvt = (at); \
1068 sim_write (sd, sp, (void *)&auxvt, 4)
1069 unsigned int egid = getegid (), gid = getgid ();
1070 unsigned int euid = geteuid (), uid = getuid ();
1071 bu32 auxvt_size = 0;
1072 AT_PUSH (AT_NULL, 0);
1073 AT_PUSH (AT_SECURE, egid != gid || euid != uid);
1074 AT_PUSH (AT_EGID, egid);
1075 AT_PUSH (AT_GID, gid);
1076 AT_PUSH (AT_EUID, euid);
1077 AT_PUSH (AT_UID, uid);
1078 AT_PUSH (AT_ENTRY, elf_addrs[4]);
1079 AT_PUSH (AT_FLAGS, 0);
1080 AT_PUSH (AT_BASE, elf_addrs[3]);
1081 AT_PUSH (AT_PHNUM, elf_addrs[2]);
1082 AT_PUSH (AT_PHENT, sizeof (Elf32_External_Phdr));
1083 AT_PUSH (AT_PHDR, elf_addrs[1]);
1084 AT_PUSH (AT_CLKTCK, 100); /* XXX: This ever not 100 ? */
1085 AT_PUSH (AT_PAGESZ, 4096);
1086 AT_PUSH (AT_HWCAP, 0);
1087 #undef AT_PUSH
1088 }
1089 SET_SPREG (sp);
1090
1091 /* Push the argc/argv/env after the auxvt. */
1092 sp -= ((1 + argc + 1 + envc + 1) * 4);
1093 SET_SPREG (sp);
1094
1095 /* First push the argc value. */
1096 sim_write (sd, sp, (void *)&argc, 4);
1097 sp += 4;
1098
1099 /* Then the actual argv strings so we know where to point argv[]. */
1100 for (i = 0; i < argc; ++i)
1101 {
1102 unsigned len = strlen (argv[i]) + 1;
1103 sim_write (sd, sp_flat, (void *)argv[i], len);
1104 sim_write (sd, sp, (void *)&sp_flat, 4);
1105 sp_flat += len;
1106 sp += 4;
1107 }
1108 sim_write (sd, sp, null, 4);
1109 sp += 4;
1110
1111 /* Then the actual env strings so we know where to point env[]. */
1112 for (i = 0; i < envc; ++i)
1113 {
1114 unsigned len = strlen (env[i]) + 1;
1115 sim_write (sd, sp_flat, (void *)env[i], len);
1116 sim_write (sd, sp, (void *)&sp_flat, 4);
1117 sp_flat += len;
1118 sp += 4;
1119 }
1120
1121 /* Set some callbacks. */
1122 cb->syscall_map = cb_linux_syscall_map;
1123 cb->errno_map = cb_linux_errno_map;
1124 cb->open_map = cb_linux_open_map;
1125 cb->signal_map = cb_linux_signal_map;
1126 cb->stat_map = stat_map_32 = cb_linux_stat_map_32;
1127 stat_map_64 = cb_linux_stat_map_64;
1128 }
1129
1130 static void
1131 bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, char * const *argv)
1132 {
1133 /* Pass the command line via a string in R0 like Linux expects. */
1134 int i;
1135 bu8 byte;
1136 bu32 cmdline = BFIN_L1_SRAM_SCRATCH;
1137
1138 SET_DREG (0, cmdline);
1139 if (argv && argv[0])
1140 {
1141 i = 1;
1142 byte = ' ';
1143 while (argv[i])
1144 {
1145 bu32 len = strlen (argv[i]);
1146 sim_write (sd, cmdline, (void *)argv[i], len);
1147 cmdline += len;
1148 sim_write (sd, cmdline, &byte, 1);
1149 ++cmdline;
1150 ++i;
1151 }
1152 }
1153 byte = 0;
1154 sim_write (sd, cmdline, &byte, 1);
1155 }
1156
1157 static void
1158 bfin_virtual_init (SIM_DESC sd, SIM_CPU *cpu)
1159 {
1160 host_callback *cb = STATE_CALLBACK (sd);
1161
1162 cb->stat_map = stat_map_32 = cb_libgloss_stat_map_32;
1163 stat_map_64 = NULL;
1164 }
1165
1166 SIM_RC
1167 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1168 char * const *argv, char * const *env)
1169 {
1170 SIM_CPU *cpu = STATE_CPU (sd, 0);
1171 SIM_ADDR addr;
1172
1173 /* Set the PC. */
1174 if (abfd != NULL)
1175 addr = bfd_get_start_address (abfd);
1176 else
1177 addr = 0;
1178 sim_pc_set (cpu, addr);
1179
1180 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1181 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1182 with `gdb`), we need to handle it because the user can change the
1183 argv on the fly via gdb's 'run'. */
1184 if (STATE_PROG_ARGV (sd) != argv)
1185 {
1186 freeargv (STATE_PROG_ARGV (sd));
1187 STATE_PROG_ARGV (sd) = dupargv (argv);
1188 }
1189
1190 switch (STATE_ENVIRONMENT (sd))
1191 {
1192 case USER_ENVIRONMENT:
1193 bfin_user_init (sd, cpu, abfd, argv, env);
1194 break;
1195 case OPERATING_ENVIRONMENT:
1196 bfin_os_init (sd, cpu, argv);
1197 break;
1198 default:
1199 bfin_virtual_init (sd, cpu);
1200 break;
1201 }
1202
1203 return SIM_RC_OK;
1204 }