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