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