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