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