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